【问题标题】:How to deal with promises in loop?如何处理循环中的承诺?
【发布时间】:2014-01-09 11:29:01
【问题描述】:
这就是我想做的事
var response = [];
Model.find().then(function(results){
for(r in results){
MyService.getAnotherModel(results[r]).then(function(magic){
response.push(magic);
});
}
});
//when finished
res.send(response, 200);
但是它只返回 [] 因为异步的东西还没有准备好。我正在使用使用 Q 承诺的sails.js。任何想法如何在所有异步调用完成后返回响应?
https://github.com/balderdashy/waterline#query-methods(承诺方法)
【问题讨论】:
标签:
node.js
promise
sails.js
q
waterline
【解决方案2】:
由于水线使用Q,您可以使用allSettled方法。
你可以找到more details on Q documentation。
Model.find().then(function(results) {
var promises = [];
for (r in results){
promises.push(MyService.getAnotherModel(results[r]));
}
// Wait until all promises resolve
Q.allSettled(promises).then(function(result) {
// Send the response
res.send(result, 200);
});
});
【解决方案3】:
您根本无法这样做,您必须等待异步函数完成。
您可以自己创建一些东西,或者使用 async 中间件,或者使用内置功能,如 Florent 的回答中所述,但无论如何我都会在此处添加其他两个:
var response = [];
Model.find().then(function(results){
var length = Object.keys(results).length,
i = 0;
for(r in results){
MyService.getAnotherModel(results[r]).then(function(magic){
response.push(magic);
i++;
if (i == length) {
// all done
res.send(response, 200);
}
});
}
});
或异步
var response = [];
Model.find().then(function(results){
var asyncs = [];
for(r in results){
asyncs.push(function(callback) {
MyService.getAnotherModel(results[r]).then(function(magic){
response.push(magic);
callback();
})
});
}
async.series(asyncs, function(err) {
if (!err) {
res.send(response, 200);
}
});
});