StephenStephen StephenStephen - 2 months ago 12
Javascript Question

Callback fires before iteration is complete

I'm using the async library in this project. One function (copied below) includes a nested loop to build a 2D Array. The callback is called before the array is completely built. I'd really like to understand why this is happening and learn more about best practices. What is the best way to solve this problem?

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

Answer

You don't seem to be using any function from the async library. The correct solution is to use 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);
});