すべてのリクエストを一度に発行することなく、これを非同期で簡単に実行できます。あなたがする必要があるのは、キューを管理することだけです。以下は、わかりやすくするための疑似コードです。実際の AJAX リクエストに簡単に変換できます。
// Basic structure of the request queue. It's a list of objects
// that defines ajax requests:
var request_queue = [{
url : "some/path",
callback : function_to_process_the_data
}];
// This function implements the main loop.
// It looks recursive but is not because each function
// call happens in an event handler:
function process_request_queue () {
// If we have anything in the queue, do an ajax call.
// Otherwise do nothing and let the loop end.
if (request_queue.length) {
// Get one request from the queue. We can either
// shift or pop depending on weather you prefer
// depth first or breadth first processing:
var req = request_queue.pop();
ajax(req.url,function(result){
req.callback(result);
// At the end of the ajax request process
// the queue again:
process_request_queue();
}
}
}
// Now get the ball rolling:
process_request_queue();
したがって、基本的には ajax 呼び出し自体を疑似ループに変えます。これは基本的に、再帰的に行われるプログラミングの古典的な継続渡しスタイルです。
あなたの場合、リクエストの例は次のようになります。
request_queue.push({
url : "path/to/OUTER/request",
callback : function (result) {
// You mentioned that the result of the OUTER request
// should trigger another round of INNER requests.
// To do this simply add the INNER requests to the queue:
request_queue.push({
url : result.inner_url,
callback : function_to_handle_inner_request
});
}
});
幅優先または深さ優先 (シフト vs ポップ) のいずれかでリクエストを処理するオプションがあるだけではないため、これは非常に柔軟です。ただし、splice を使用してキューの途中に追加したり、unshift vs push を使用して優先度の高いリクエストのキューの先頭にリクエストを配置したりすることもできます。
ループごとに複数のリクエストをポップすることで、同時リクエストの数を増やすこともできます。process_request_queue
同時リクエストが指数関数的に増加するのを避けるために、ループごとに 1 回だけ呼び出すようにしてください。
// Handling two simultaneous request channels:
function process_request_queue () {
if (request_queue.length) {
var req = request_queue.pop();
ajax(req.url,function(result){
req.callback(result);
// Best to loop on the first request.
// The second request below may never fire
// if the queue runs out of requests.
process_request_queue();
}
}
if (request_queue.length) {
var req = request_queue.pop();
ajax(req.url,function(result){
req.callback(result);
// DON'T CALL process_request_queue here
// We only want to call it once per "loop"
// otherwise the "loop" would grow into a "tree"
}
}
}