javascript - node异步问题
问题描述
想要callback在findById之后执行,但又不能放在它的回调中,不然会执行多次。应该怎么办?
问题解答
回答1:软件是服务行业,要有服务意识……代码贴图没问题,可以看得很清晰,但是如果回答者想改你的代码,还得重新敲一遍…………
我看你已经用了 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() 中的回调。
如果你要用 es5,建议你写成 es6 再 Babel。不过 Node 7.6+ 已经支持 es2017 的一些特性,所以其实不必在意这个问题。如果确实需要,就采用在 findById 回调中记数的办法,记满放大招(调用 callback)。
回答2:方案一
使用 async/await。这样就可以按照同步方式使用 User.findById。
方案二
在循环中把 User.findById 加入一个数组,然后用 Promise.all,callback 写在 Promise.all().then() 中。
方案三
使用一个状态变量,每次检查一下,满足条件再执行 callback。丑陋的方法,不要用。
回答3:设置个参数,执行完设置下,以后每次进入回调判断下 ..
回答4:对于callback地狱,请使用Promise 或者类似类库。
回答5: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。。?
回答6:二楼说得对,用promise解决。
相关文章:
1. 主从备份 - 跪求mysql 高可用主从方案2. python - django 里自定义的 login 方法,如何使用 login_required()3. python如何不改动文件的情况下修改文件的 修改日期4. mysql主从 - 请教下mysql 主动-被动模式的双主配置 和 主从配置在应用上有什么区别?5. angular.js - 不适用其他构建工具,怎么搭建angular1项目6. android-studio - Android 动态壁纸LayoutParams问题7. mysql优化 - mysql count(id)查询速度如何优化?8. javascript - git clone 下来的项目 想在本地运行 npm run install 报错9. sql语句如何按or排序取出记录10. node.js - 使用 superagent 抓取 UTF-8网站乱码
