84669 人学习
152542 人学习
20005 人学习
5487 人学习
7821 人学习
359900 人学习
3350 人学习
180660 人学习
48569 人学习
18603 人学习
40936 人学习
1549 人学习
1183 人学习
32909 人学习
想要callback在findById之后执行,但又不能放在它的回调中,不然会执行多次。应该怎么办?
光阴似箭催人老,日月如移越少年。
软件是服务行业,要有服务意识……代码贴图没问题,可以看得很清晰,但是如果回答者想改你的代码,还得重新敲一遍…………
我看你已经用了 es6 的语法,所以正解肯定是 Promise,可以自己封装成 Promies
exports.findList = function(findObj, callback) { Info.find(findObj, function(err, info) { const promises = info.map(f => new Promise((resolve, reject) => { f.image = f.images.split(",")[0]; User.findById(f.author_id, function(error, user) { if (error) { reject(error); return; } f.author_name = user.name; f.authro_avatar = user.avatar; resolve(f); }); })); Promise.all(promises) .then(function(values) { // 成功的时候,这个 values 是所有 info 对象, // 作为一个数组返回出来,而不是某一个 callback(null, values); }) .catch(function(error) { // 注意这里 error 是第一个失败 error // 不是所有的 error callback(error); }); }); };
当然也可以用 Bluebird 提供的工具函数来封装 Promise
需要注意的是你这里运行了好多个异步调用,所以要一起返回的话,肯定也是好多个结果。所以注意 Promise.all 后面 then() 中的回调。
Promise.all
then()
如果你要用 es5,建议你写成 es6 再 Babel。不过 Node 7.6+ 已经支持 es2017 的一些特性,所以其实不必在意这个问题。如果确实需要,就采用在 findById 回调中记数的办法,记满放大招(调用 callback)。
findById
方案一
使用 async/await。这样就可以按照同步方式使用 User.findById。
async/await
User.findById
方案二
在循环中把 User.findById 加入一个数组,然后用 Promise.all,callback 写在 Promise.all().then() 中。
callback
Promise.all().then()
方案三
使用一个状态变量,每次检查一下,满足条件再执行 callback。丑陋的方法,不要用。
设置个参数,执行完设置下,以后每次进入回调判断下 ..
对于callback地狱,请使用Promise 或者类似类库。
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。。?
二楼说得对,用promise解决。
我看你已经用了 es6 的语法,所以正解肯定是 Promise,可以自己封装成 Promies
当然也可以用 Bluebird 提供的工具函数来封装 Promise
需要注意的是你这里运行了好多个异步调用,所以要一起返回的话,肯定也是好多个结果。所以注意
Promise.all
后面then()
中的回调。如果你要用 es5,建议你写成 es6 再 Babel。不过 Node 7.6+ 已经支持 es2017 的一些特性,所以其实不必在意这个问题。如果确实需要,就采用在
findById
回调中记数的办法,记满放大招(调用 callback)。方案一
使用
async/await
。这样就可以按照同步方式使用User.findById
。方案二
在循环中把
User.findById
加入一个数组,然后用Promise.all
,callback
写在Promise.all().then()
中。方案三
使用一个状态变量,每次检查一下,满足条件再执行
callback
。丑陋的方法,不要用。设置个参数,执行完设置下,以后每次进入回调判断下 ..
对于callback地狱,请使用Promise 或者类似类库。
我的解决方法,有点low。。?
二楼说得对,用promise解决。