我在这个项目中使用async库。一个函数(下面复制)包括用于构建2D数组的嵌套循环。在完全构建数组之前调用回调。我真的很想了解为什么会这样,并了解有关最佳做法的更多信息。解决这个问题的最佳方法是什么?
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?
}
答案 0 :(得分:1)
一种方法是使用本机承诺并等待异步调用完成
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 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) { ... })
答案 1 :(得分:1)
您似乎没有使用async
库中的任何功能。正确的解决方案是使用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);
});