想要callback在findById之后执行,但又不能放在它的回调中,不然会执行多次。应该怎么办?
方案一
使用 async/await
。这样就可以按照同步方式使用 User.findById
。
方案二
在循环中把 User.findById
加入一个数组,然后用 Promise.all
,callback
写在 Promise.all().then()
中。
方案三
使用一个状态变量,每次检查一下,满足条件再执行 callback
。丑陋的方法,不要用。
exports.findList=function (findObj,callback) {
Info.find(findObj,function (err,info) {
for(let i in info){
info[i].image=info[i].images.split(',')[0];
User.findById(info[i].author_id,function (error,user) {
info[i].author_name=user.name;
info[i].author_avatar=user.avatar;
if(i==info.length-1){
callback(err,info);
}
})
}
})
}
我的解决方法,有点low。。?
27 回答12.8k 阅读
8 回答3.4k 阅读✓ 已解决
6 回答1.1k 阅读✓ 已解决
5 回答5.2k 阅读✓ 已解决
4 回答1.5k 阅读✓ 已解决
3 回答1.7k 阅读
4 回答2.3k 阅读✓ 已解决
我看你已经用了 es6 的语法,所以正解肯定是 Promise,可以自己封装成 Promies
当然也可以用 Bluebird 提供的工具函数来封装 Promise
需要注意的是你这里运行了好多个异步调用,所以要一起返回的话,肯定也是好多个结果。所以注意
Promise.all
后面then()
中的回调。如果你要用 es5,建议你写成 es6 再 Babel。不过 Node 7.6+ 已经支持 es2017 的一些特性,所以其实不必在意这个问题。如果确实需要,就采用在
findById
回调中记数的办法,记满放大招(调用 callback)。