我有一个函数,我循环并执行一小组查询,使用Breeze.js返回数据块。代码的每个部分都可以工作但只有一行(我尝试将查询结果添加到数组中)。我尝试了各种各样的东西,似乎无法弄清楚为什么它不起作用。
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);
}
}
}
答案 0 :(得分:4)
getSucceeded
被称为异步,这意味着您将其作为回调传递给EntityQuery
,后者将在以后将其称为 。
当您的_.each(sourceArray, ...)
返回时,所有查询都已启动但仍在运行。这些都还没有完成,你的回调也没有被调用过。因此,arr
在您将其传递给outputObservable
时仍然保持不变。您应该能够在调试器中注意到这一点:在console.log
之前添加outputObservable
,您会看到之前在console.log(item)
之前调用调用
您只想在所有异步查询完成时调用outputObservable
。我对Breeze或underscore.js不太熟悉,但你需要将execute()
返回的承诺合并到一个新的承诺中。当所有承诺得到解决时,此新承诺就会得到解决,因此您应该附加一个then
回调并致电outputObservable
。