簡體   English   中英

在迭代完成之前觸發回調

[英]Callback fires before iteration is complete

我在這個項目中使用了異步庫。 一個函數(復制如下)包括一個用於構建二維數組的嵌套循環。 在數組完全構建之前調用回調。 我真的很想了解為什么會發生這種情況並了解有關最佳實踐的更多信息。 解決這個問題的最佳方法是什么?

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? 
    }

一種方法是只使用本機承諾並等待異步調用完成

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);
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM