私はjQueryを使用しています。また、アプリケーションで並列AJAX呼び出しは必要ありません。各呼び出しは、開始する前に前の呼び出しを待機する必要があります。それを実装する方法は?ヘルパーはいますか?
UPDATEXMLHttpRequestまたはjQuery.postの同期バージョンがある場合は知りたいです。しかし、シーケンシャル!=同期であり、非同期のシーケンシャルソリューションが必要です。
私はjQueryを使用しています。また、アプリケーションで並列AJAX呼び出しは必要ありません。各呼び出しは、開始する前に前の呼び出しを待機する必要があります。それを実装する方法は?ヘルパーはいますか?
UPDATEXMLHttpRequestまたはjQuery.postの同期バージョンがある場合は知りたいです。しかし、シーケンシャル!=同期であり、非同期のシーケンシャルソリューションが必要です。
これを行うには、同期 ajax 呼び出しを使用するよりもはるかに優れた方法があります。Jquery ajax は deferred を返すため、パイプ チェーンを使用するだけで、各 ajax 呼び出しが次の実行前に終了することを確認できます。jsfiddle で遊ぶことができる、より詳細な例を含む実際の例を次に示します。
// How to force async functions to execute sequentially
// by using deferred pipe chaining.
// The master deferred.
var dfd = $.Deferred(), // Master deferred
dfdNext = dfd; // Next deferred in the chain
x = 0, // Loop index
values = [],
// Simulates $.ajax, but with predictable behaviour.
// You only need to understand that higher 'value' param
// will finish earlier.
simulateAjax = function (value) {
var dfdAjax = $.Deferred();
setTimeout(
function () {
dfdAjax.resolve(value);
},
1000 - (value * 100)
);
return dfdAjax.promise();
},
// This would be a user function that makes an ajax request.
// In normal code you'd be using $.ajax instead of simulateAjax.
requestAjax = function (value) {
return simulateAjax(value);
};
// Start the pipe chain. You should be able to do
// this anywhere in the program, even
// at the end,and it should still give the same results.
dfd.resolve();
// Deferred pipe chaining.
// What you want to note here is that an new
// ajax call will not start until the previous
// ajax call is completely finished.
for (x = 1; x <= 4; x++) {
values.push(x);
dfdNext = dfdNext.pipe(function () {
var value = values.shift();
return requestAjax(value).
done(function(response) {
// Process the response here.
});
});
}
一部の人々は、コードが何をするのか見当がつかないとコメントしています。それを理解するには、まず JavaScript の promise を理解する必要があります。Promise は間もなくネイティブの JavaScript 言語の機能になると確信しているので、学習する良いインセンティブになるはずです。
私が考えることができる 2 つの選択肢があります。1 つは、コールバックを介してチェーンすることです。もう 1 つは、呼び出しを非同期ではなく同期にすることです。
それらを順次にしたい理由はありますか?それは物事を遅くします。
呼び出しを同期させるには、Ajax 呼び出しの async オプションを false に設定します。http://docs.jquery.com/Ajax/jQuery.ajax#optionsのドキュメントを参照してください (オプション タブをクリックして参照してください)。
これを行う最善の方法は、Nosredna が言ったようにコールバックを連鎖させることです。アプリケーション全体をロックするため、同期 XMLHttpRequest を使用することはお勧めしません。
私の知る限り、これに対するヘルパーはあまりありませんが、コールバック FIFO に似た何かを行うことができます。
物語のJavaScriptを試してみてください http://www.neilmix.com/narrativejs/doc/
自分は使ったことないですけどね。これを行うには、非同期アクションをチェーンするためのある種の抽象化をセットアップします。他の人が言ったように、ajax オブジェクトの同期バージョンは、応答を待っている間、イベントの処理をブロックします。これにより、ブラウザーは応答を受信するまでフリーズしているように見えます。
asyncオプションを false に設定します。
$.ajax({ async: false /*, your_other_ajax_options_here */ });
これを見てください:http://docs.jquery.com/Ajax/jQuery.ajax (「オプション」タブをクリックします)。
ただし、同期呼び出しは応答が受信されるまでページをフリーズさせるため、本番サイトでは使用できません。ブラウザーがフリーズした状態で何らかの理由で 30 秒待たなければならない場合、ユーザーは怒ってしまうからです。
編集:わかりました、更新すると、達成したいことがより明確になります;)
したがって、コードは次のようになります。
$.getJSON("http://example.com/jsoncall", function(data) {
process(data);
$.getJSON("http://example.com/jsoncall2", function (data) {
processAgain(data);
$.getJSON("http://example.com/anotherjsoncall", function(data) {
processAgainAndAgain(data);
});
});
});
このように、2 番目の呼び出しは、最初の呼び出しに対する応答が受信および処理されたときにのみ発行され、3 番目の呼び出しは、2 番目の呼び出しに対する応答が受信および処理されたときにのみ発行されます。このコードは getJSON 用ですが、$.ajax に適合させることができます。
同期呼び出しは必ずしも遅いとは限りません。AJAX 呼び出しが開いてソケットにポストし、ソケットを閉じるアプリがある場合、一部のソケットは単一の接続しか処理できないため、ソケットへの複数の呼び出しは意味がありません。前の AJAX 呼び出しが完了したときにのみ送信されるようにデータをキューに入れると、データ スループットが大幅に向上します。
Node.js イベントを使用するのはどうですか?
var EventEmitter = require('events').EventEmitter;
var eventEmitter = new EventEmitter();
var $ = require('jquery');
var doSomething = function (responseData) {
var nextRequestData = {};
// do something with responseData
return nextRequestData;
};
// ajax requests
var request1 = $.ajax;
var request2 = $.ajax;
var requests = [request1, request2];
eventEmitter.on('next', function (i, requestData) {
requests[i](requestData).then(
function (responseData) {
console.log(i, 'request completed');
if (i+1 < requests.length) {
var nextRequestData = doSomething(responseData);
eventEmitter.emit('next', i+1, nextRequestData);
}
else {
console.log('completed all requests');
}
},
function () {
console.log(i, 'request failed');
}
);
});
var data = {
//data to send with request 1
};
eventEmitter.emit('next', 0, data);
sequential != synchronous, and I would like an asynchronous and sequential solution
Synchronous execution generally means "using the same clock", while sequential execution means "following in order or sequence".
For your specific use case I think both conditions must be met, as asynchronous execution implies the possibility of a non-sequential result.