関数を使用して同時に実行する ajax リクエストがいくつかあります (5 としましょう)。jQuery.ajax
ここで、結果を同期して集計したいと思いjQuery.when
ます。関数を使用してこれを実現しました。
私の問題は$.when
、リクエストの1つが失敗するとすぐに戻り、他のリクエストが成功しても戻らないことです。
すべての ajax リクエスト (失敗したものと成功したもの)からすべての結果を同期して取得するにはどうすればよいですか?
実際のデモ: http://jsbin.com/ocawoj/4/edit
function waitForAllPromisesToFinish () {
var i,
responses = [],
deferred = $.Deferred(),
helpers = {
addToResponses: function (index, data) {
responses[index] = data;
var i = 0,
isAnyNull = false;
for (i = 0; i < responses.length; i++) {
if (responses[i] === null) {
isAnyNull = true;
break;
}
}
if (isAnyNull === false) {
deferred.resolve(responses);
}
},
setupPromise: function (promise, index) {
promise.always(function () {
var args = Array.prototype.slice.call(arguments);
helpers.addToResponses(index, args);
});
}
},
ajaxPromises = Array.prototype.slice.call(arguments);
for (i = 0; i < ajaxPromises.length; i++) {
responses[i] = null;
}
for (i = 0; i < ajaxPromises.length; i++) {
helpers.setupPromise(ajaxPromises[i], i);
}
return deferred.promise();
}
関数は promise を返します。$.when() に提供するものとは少し異なる done ハンドラーをアタッチします。この関数は、各 ajax promise の応答を追跡します。すべての ajax promise が成功または失敗のいずれかのデータを返したことを検出すると、promise を解決します。
これは私が最初に考えたものですが、同じことを達成するためのより効率的な方法があるかもしれません.
対応する promise (ajax コールバック) の応答を取得する 1 つ、2 つ、または 3 つの更新関数 (何をしたいかによって異なります) を定義できます。
function bindPromises(updateSuccess, updateFail, updateAnyway) {
var arrPromises = [];
// automate the promise retrieval if you want, that's up to you.
arrPromises[0] = ajaxRequest1();
arrPromises[1] = ajaxRequest2();
arrPromises[2] = ajaxRequest3();
arrPromises[3] = ajaxRequest4();
arrPromises[4] = ajaxRequest5();
for(var j = 0; j < arrPromises.length; j++) {
arrPromises[j].then( updateSuccess, updateFail, updateAnyway );
}
}
または、さらに自動化したい場合は、次のようにします。
function bindPromises(arrayOfAjaxCalls, updateSuccess, updateFail, updateAnyway) {
var arrPromises = [];
for(var i = 0; i < arrayOfAjaxCalls.length; i++) {
arrPromises[i] = (arrayOfAjaxCalls[i])();
arrPromises[i].then( updateSuccess, updateFail, updateAnyway );
}
}
Promises に慣れていない場合は、そのトピックをカバーする素晴らしい記事を紹介したいと思います: Understanding jQuery.Deferred and Promise