それぞれが他のajax呼び出しをトリガーするいくつかのajax呼び出しがあります。次に、それらからのデータを処理するために後者を待ちたいと思います。(擬似)コードは次のとおりです。https ://gist.github.com/2795435問題は、配列のすべての遅延が解決/拒否される前
に、2番目の式のコールバック関数$.when-alwaysがトリガーされることです。promises2どうすればいいの?$.when-always私が見ているように、promise1配列のすべての遅延が解決/拒否されるまで、最初のコールバックは呼び出されません。その時点で、のすべてのajax呼び出しpromises2が行われるため、2番目のコールバックは$.when-alwaysすべての遅延まで呼び出されません。でpromises2解決/拒否されました。
1 に答える
では、最後に応答した に関連付けられたコールバックを起動する前にawait()、jQuery がの always コールバックを起動するように見えます。したがって、 では、インナーがその always コールバックを起動するときに、配列は 1 つの promise を欠いています。promises1 getJsonawait()promises2.when()
私が正しければ、( .get()json 応答ごとに 1 つ) テストを実行して、すべての場合において、 が呼び出されたときに内側.getの s の 1 つを除くすべて (決して多くも少なくもありません) が完了することを示すことができるはずですdoSomethingToTheDataStoredInSomeGlobalVariableBelow()。
私が正しいかどうかにかかわらず、回避策(私が確信している唯一のものではありません)は、次の行に沿ったものになります:
function A() {
var promisesA = [];
for (var i = start; i < end; i++) {
promisesA.push( B(someUri) );
}
$.when.apply($, promisesA).always(function() {
doSomethingToTheDataStoredInSomeGlobalVariableBelow();
});
}
function B(uri) {
var d = new $.Deferred(),
promisesB = [];
$.getJSON(uri, function(data) {
someCollectionFrom_data.each(function () {
promisesB.push($.get(someUriFrom_this, function(data) {
extractSomeStuffFrom_data_AndStoreInSomeGlobalVariable();
}));
});
$.when.apply($, promisesB).done(function() {
d.resolve();
}).fail(function() {
d.reject();
});
}).error(function(){
d.reject();
});
return d;
}
これはデモです - フィドルとして機能するようにコードを修正しました。
ここで (バグを除いて)、配列には以前と同じように1promisesAつが取り込まれますが、今回は、対応するが解決/失敗したときに、これらの Deferred が自動的に解決されることは許可されていません。代わりに、関連付けられているすべてが関数の配列で管理されているように解決/失敗した場合、各 Deferred は「手動で」解決されます(そのうち、によって形成されたクロージャにそれぞれキャプチャされたいくつかのインスタンスがあります)。$.DeferredurigetJSON.get()sB()promisesBB()
.json()sこのスキーマは、 ajax 呼び出し (および.get()s) の「下向き」のカスケードと、 の相互の「上向き」のカスケードと見なすことができます.always()s。(混合.done()/ .fail()/.always()は等しく適用されます。)