2016-09-21 22 views
2

私はこのプロジェクトでasyncライブラリを使用しています。 1つの関数(下にコピーされています)には、2D配列を構築するネストループが含まれています。コールバックは、配列が完全に構築される前に呼び出されます。なぜこれが起こっているのかを理解し、ベストプラクティスについてもっと学びたいと思っています。この問題を解決する最良の方法は何ですか?非同期は、単に「反復が完了する前にコールバックが発生する

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

。 – choz

+0

非同期関数のループのように見えますが、すべてコールするのを待たずにコールバックを呼び出します。 –

答えて

1

あなたはドンthenableが良いだろう全体の機能を作る

を完了するために呼び出すため

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

ありがとう!これはまさに私が探していたものです。 – StephenStephen

1

一つの方法は、単にネイティブの約束を使用して待つことであろうライブラリはasyncの関数を使用しているようです。正解は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); 
}); 
関連する問題