如何优雅的解决循环里的异步查询?
最近项目里有个问题一直困扰了我挺久的,需要在循环里去查找数据库,把查询到的数据push到一个数组里,并且在循环完成后才返还,现在我想到的是在循环里面加入了个立即执行函数,将循环变量传入立即执行函数,除此之外还有其他好的写法吗?,还有我如何知道这个循环什么时候完成了呢? 伪代码: var results; for(var i=0;i<docs.length;i++){ (function(i){ db.findOne({_id : docs[i]._id},function(err,collection){ results.push(collection); }) }){i} } res.end(JSON.stringify(results)); //[] 希望有大大给我解决下困惑,非常感谢
12 回复
使用Promise吧
function promise(id) {
return new Promise(function (reslove, reject) {
db.findOne({_id: id._id}, function (err, collection) {
if (err) {
return reject(err);
}
resolve(collection);
});
});
}
let arr = docs.map(item=>promise(docs[item]));
Promise.all(arr).then(results=>res.end(JSON.stringify(results))).catch(err=>console.error(err));
或者用Generator函数,更加接近常用的逻辑
function _gen(req, res, next) {
let results = [];
for (let i = 0; i < docs.length; i++) {
let resTmp = yield promiseFindOne(docs[i]._id);
results.push(resTmp);
}
res.end(JSON.stringify(results));
}
app.get('/', function (req, res, next) {
require('co')(_gen, req, res, next).catch(err=>next(err));
});