想要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解決。