迭代完成前,callback触发

我在这个项目中使用asynchronous库。 一个函数(下面复制)包括一个嵌套循环来build立一个二维数组。 在完全构build数组之前调用callback函数。 我真的很想知道为什么会发生这种情况,并了解更多最佳实践。 解决这个问题的最好方法是什么?

function getStopTimesForTrips(cb) { timeTable.listOfTripIds.forEach(function(id){ retrieveTimesByTrip(id, function(err, st){ var tempArray = []; st.forEach(function(st){ tempArray.push(st.arrival_time); }); timeTable.stopTimes.push(tempArray); }); }); // cb(null, timeTable); <- This line fires the callback before we finish building the array. setTimeout(function(){cb(null, timeTable);},2500); // This effective solution is poor form. What's the correct way to solve this issue? } 

你似乎没有使用async库中的任何function。 正确的解决scheme是使用async

 async.each(timeTable.listOfTripIds,function(id,cb2){ retrieveTimesByTrip(id, function(err, st){ var tempArray = []; st.forEach(function(st){ tempArray.push(st.arrival_time); }); timeTable.stopTimes.push(tempArray); cb2(err); // Need to call this to tell async this iteration // is done. Think of it as an async "return". }); },function(err){ // if we're here it means the `async.each` is done: cb(null, timeTable); }); 

一种方法是只使用本地承诺,并等待asynchronous调用完成

 function getStopTimesForTrips(cb) { var promises = timeTable.listOfTripIds.map(function(id) { return new Promise(function(resolve, reject) { retrieveTimesByTrip(id, function(err, st) { if (err) return reject(); timeTable.stopTimes = st.map(function(item) { return item.arrival_time; })); resolve(); }); }); }); Promise.all(promises).then(function() { cb(null, timeTable); }); } 

只是使整个function可以更好

 function getStopTimesForTrips() { return Promise.all( timeTable.listOfTripIds.map(function(id) { return new Promise(function(resolve, reject) { retrieveTimesByTrip(id, function(err, st) { if (err) return reject(); resolve( st.map(function(item) { return item.arrival_time; }) ); }); }); }) ); } getStopTimesForTrips().then(function(arrival_times) { ... })