Javascript 在迭代完成之前触发回调

Javascript 在迭代完成之前触发回调,javascript,node.js,Javascript,Node.js,我正在这个项目中使用这个库。一个函数(复制如下)包含用于构建二维阵列的嵌套循环。在数组完全构建之前调用回调。我真的很想了解为什么会发生这种情况,并了解更多关于最佳实践的信息。解决这个问题的最好办法是什么 function getStopTimesForTrips(cb) { timeTable.listOfTripIds.forEach(function(id){ retrieveTimesByTrip(id, function(err, st){

我正在这个项目中使用这个库。一个函数(复制如下)包含用于构建二维阵列的嵌套循环。在数组完全构建之前调用回调。我真的很想了解为什么会发生这种情况,并了解更多关于最佳实践的信息。解决这个问题的最好办法是什么

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? 
    }
函数getStopTimesForTrips(cb){ timeline.listofTripID.forEach(函数(id){ retrieveTimesByTrip(id,函数(err,st){ var tempArray=[]; st.forEach(功能(st){ tempArray.push(圣到达时间); }); 时间表。停车时间。推送(临时数组); }); });
//cb(null,timeline);一种方法是只使用本机承诺并等待异步调用完成

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) { ... })

您似乎没有使用
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);
});

您甚至没有使用库提供的
async
方法。看起来像是一个异步函数的循环,但您可以在不等待所有函数都被调用的情况下调用回调函数。谢谢!这正是我要找的。