Javascript 为什么我不能在这个特定函数中添加到数组中?
我有一个函数,在这个函数中,我使用Breeze.js循环并执行一小部分查询,返回数据块。代码的每一部分都有效,只有一行我尝试将查询结果添加到数组中。我试过各种各样的方法,但似乎都不明白为什么不起作用Javascript 为什么我不能在这个特定函数中添加到数组中?,javascript,Javascript,我有一个函数,在这个函数中,我使用Breeze.js循环并执行一小部分查询,返回数据块。代码的每一部分都有效,只有一行我尝试将查询结果添加到数组中。我试过各种各样的方法,但似乎都不明白为什么不起作用 function doStuff(sourceArray, outputObservable, errorObservable) { var arr = []; _.each(sourceArray, function (sourceItem) { return b
function doStuff(sourceArray, outputObservable, errorObservable) {
var arr = [];
_.each(sourceArray, function (sourceItem) {
return breeze.EntityQuery
.from("SomeTable")
.using(manager).execute()
.then(getSucceeded)
.fail(getFailed);
function getSucceeded(data) {
_.each(data.results, function (item) {
console.log(item); //This works
arr.push(item); //This doesn't work
});
}
function getFailed(error) {
errorObservable("Error retrieving data: " + error.message);
}
});
outputObservable(arr);
}
这会将每个查询的所有结果输出到控制台,但不会将结果发送到数组。但是,如果我将第二行更改为var arr=[1,2,3,4,5];然后这些值将反映在outputObservable中
编辑:完整的解决方案如下
function doStuff(sourceArray, outputObservable, errorObservable) {
var promises = [];
var arr = [];
//Create an array of promises
_.forEach(sourceArray, function (item) {
promises.push(getDataFromServer(item.val1, item.val2));
});
//Wait for all promises to resolve, then set output
Q.all(promises).then(function () {
outputObservable(arr);
});
function getDataFromServer(filter1, filter2) {
var p1 = breeze.Predicate.create("field1", "==", filter1);
var p2 = breeze.Predicate.create("field2", "==", filter2);
return breeze.EntityQuery
.from("SomeTable")
.where(p1.and(p2))
.using(manager).execute()
.then(getSucceeded)
.fail(getFailed);
function getSucceeded(data) {
_.each(data.results, function (item) {
arr.push(item);
});
}
function getFailed(error) {
errorObservable("Error retrieving processes: " + error.message);
}
}
}
啊,异步的经典陷阱。GetSucceed是异步调用的,这意味着您将它作为回调传递给EntityQuery,EntityQuery随后将调用它 当你的每个资源阵列。。。返回,所有查询将已启动但仍在运行。这些都还没有完成,您的回调也还没有被调用。因此,当您将arr传递给outputObservable时,它仍然保持不变。您应该能够在调试器中注意到这一点:在outputObservable之前添加一个console.log,您将看到它将在任何console.logitem调用之前被调用
您只希望在所有异步查询完成后调用outputObservable。我不太熟悉Breeze或underline.js,但您需要将execute返回的承诺组合成一个新的承诺。当所有的承诺都得到解决时,这个新的承诺就会得到解决,因此您应该给它附加一个then回调,并调用outputObservable。啊,异步的经典陷阱。GetSucceed是异步调用的,这意味着您将它作为回调传递给EntityQuery,EntityQuery随后将调用它 当你的每个资源阵列。。。返回,所有查询将已启动但仍在运行。这些都还没有完成,您的回调也还没有被调用。因此,当您将arr传递给outputObservable时,它仍然保持不变。您应该能够在调试器中注意到这一点:在outputObservable之前添加一个console.log,您将看到它将在任何console.logitem调用之前被调用
您只希望在所有异步查询完成后调用outputObservable。我不太熟悉Breeze或underline.js,但您需要将execute返回的承诺组合成一个新的承诺。当所有承诺都得到解决时,这个新承诺就会得到解决,因此您应该向它附加一个然后回调,并调用outputObservable。什么不起作用?没有迹象表明该行是否/何时运行,它不会在结果中添加任何内容。因此,一个有效的假设是它永远不会运行;或者运行不够快。我不熟悉Breeze,但我怀疑EntityQuery是异步的?如果是这样,则将在触发回调GetSuccessed之前调用outputObservable。。。。但是您应该能够从console.log.Doh中看到这一点,这是因为outputObservablearr首先被调用=/。什么不起作用?没有迹象表明该行是否/何时运行,它不会在结果中添加任何内容。因此,一个有效的假设是它永远不会运行;或者运行不够快。我不熟悉Breeze,但我怀疑EntityQuery是异步的?如果是这样,则将在触发回调GetSuccessed之前调用outputObservable。。。。但是您应该能够从console.log.Doh中看到这一点,这是因为outputObservablearr首先被调用=/。Breeze使用Q作为它的承诺。在这个forEach循环中,我如何将承诺结合起来呢?没关系,我玩了一会儿,找到了一个解决方案。编辑后的答案显示。微风使用引擎盖下的Q作为它的承诺。在这个forEach循环中,我如何将承诺结合起来呢?没关系,我玩了一会儿,找到了一个解决方案。编辑答案以显示。