あなたはあなたのコードをあまり具体的にしていなかったので、シナリオを作ります。10個のajax呼び出しがあり、それらの10個のajax呼び出しからの結果を蓄積したいとし、それらがすべて完了したら何かを実行したいとします。配列にデータを蓄積し、最後のデータがいつ終了したかを追跡することで、次のように行うことができます。
手動カウンター
var ajaxCallsRemaining = 10;
var returnedData = [];
for (var i = 0; i < 10; i++) {
doAjax(whatever, function(response) {
// success handler from the ajax call
// save response
returnedData.push(response);
// see if we're done with the last ajax call
--ajaxCallsRemaining;
if (ajaxCallsRemaining <= 0) {
// all data is here now
// look through the returnedData and do whatever processing
// you want on it right here
}
});
}
注:エラー処理はここで重要です(それはajax呼び出しを行う方法に固有であるため、表示されていません)。1つのajax呼び出しがエラーで終了しないか、長時間停止したり、長時間経過した後にタイムアウトになったりした場合の処理方法を検討する必要があります。
jQueryの約束
2014年の私の回答に追加します。最近では、jQueryが$.ajax()
既にプロミスを返し、プロミス$.when()
のグループがすべて解決され、返された結果を収集するので、このタイプの問題を解決するためにプロミスがよく使用されます。
var promises = [];
for (var i = 0; i < 10; i++) {
promises.push($.ajax(...));
}
$.when.apply($, promises).then(function() {
// returned data is in arguments[0][0], arguments[1][0], ... arguments[9][0]
// you can process it here
}, function() {
// error occurred
});
ES6標準の約束
kbaの回答で指定されているように、ネイティブのpromiseが組み込まれている環境(モダンブラウザーまたはnode.js、あるいはbabeljsトランスパイルまたはpromiseポリフィルの使用)がある場合、ES6で指定されたpromiseを使用できます。ブラウザのサポートについては、この表を参照してください。Promiseは、IEを除くほとんどすべての現在のブラウザーでサポートされています。
doAjax()
がpromiseを返す場合、これを行うことができます:
var promises = [];
for (var i = 0; i < 10; i++) {
promises.push(doAjax(...));
}
Promise.all(promises).then(function() {
// returned data is in arguments[0], arguments[1], ... arguments[n]
// you can process it here
}, function(err) {
// error occurred
});
Promise以外の非同期操作をPromiseを返すものにする必要がある場合は、次のように「Promisify」できます。
function doAjax(...) {
return new Promise(function(resolve, reject) {
someAsyncOperation(..., function(err, result) {
if (err) return reject(err);
resolve(result);
});
});
}
そして、上記のパターンを使用します:
var promises = [];
for (var i = 0; i < 10; i++) {
promises.push(doAjax(...));
}
Promise.all(promises).then(function() {
// returned data is in arguments[0], arguments[1], ... arguments[n]
// you can process it here
}, function(err) {
// error occurred
});
ブルーバードプロミス
Bluebird promiseライブラリーなど、より機能の豊富なライブラリーを使用する場合は、これを容易にするためにいくつかの追加機能が組み込まれています。
var doAjax = Promise.promisify(someAsync);
var someData = [...]
Promise.map(someData, doAjax).then(function(results) {
// all ajax results here
}, function(err) {
// some error here
});