web-dev-qa-db-ja.com

すべてのAJAX呼び出しをシーケンシャルにする方法は?

私はjQueryを使用しています。そして、アプリケーションで並列AJAX呼び出しをしたくないので、各呼び出しは開始する前に前の呼び出しを待つ必要があります。それを実装する方法はありますか?

[〜#〜] update [〜#〜] XMLHttpRequestまたはjQuery.postの同期バージョンがある場合は知りたいです。しかし、シーケンシャル!=同期であり、非同期のシーケンシャルソリューションが必要です。

23
Jader Dias

これを行うには、同期ajax呼び出しを使用するよりもはるかに優れた方法があります。 Jquery ajaxは遅延を返すため、パイプチェーンを使用して、次の実行前に各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の約束を理解する必要があります。約束はまもなくネイティブのJavaScript言語機能になると確信しているので、それはあなたに学ぶための良いインセンティブを与えるはずです。

17
Todd Chaffee

私が考えることができる2つの選択肢があります。 1つは、コールバックを介してそれらをチェーンすることです。もう1つは、呼び出しを非同期ではなく同期にすることです。

それらをシーケンシャルにしたい理由はありますか?それは物事を遅くします。

呼び出しを同期させるには、Ajax呼び出しのasyncオプションをfalseに設定します。 http://docs.jquery.com/Ajax/jQuery.ajax#options のドキュメントを参照してください(オプションタブをクリックして表示してください)。

6
Nosredna

物語のJavaScriptを試してみることができます http://www.neilmix.com/narrativejs/doc/

私はそれを自分で使ったことがありません。これを実行したい場合は、非同期アクションを連鎖させるためのある種の抽象化を設定します。他の人が言っているように、ajaxオブジェクトの同期バージョンは、応答を待っている間、イベントが処理されるのをブロックします。これにより、ブラウザは応答を受信するまでフリーズしたように見えます。

2
Breton

これを見てください: 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に適合させることができます。

1
FWH

これを行うための最良の方法は、Nosrednaが言ったようにコールバックを連鎖させることです。同期XMLHttpRequestを使用すると、アプリケーション全体がロックされるため、お勧めしません。

私の知る限り、これに対するヘルパーはあまりありませんが、コールバックFIFOに似た何かを行うことができます。

1
Gab Royer

asyncオプションをfalseに設定します(例:

$.ajax({ async: false /*, your_other_ajax_options_here */ });

参照: Ajax/jQuery.ajax

1
Joe Chung

そして今、あなたはこれに対する解決策を持っているようです:

http://api.jquery.com/category/deferred-object/

または

http://www.slideshare.net/furf/making-ajax-sexy-jsconf-2010?from=ss_embed

1
llamerr

Promiseを使用して、ajax呼び出しを順次行うことができます。 ArrayPushとpoppromiseメソッドを使用すると、順次ajax呼び出しがはるかに簡単になります。

var promises = [Promise.resolve()];

function methodThatReturnsAPromise(id) {
  return new Promise((resolve, reject) => {
    $.ajax({
      url: 'https://jsonplaceholder.typicode.com/todos/'+id,
      dataType:'json',
      success: function(data)
      {
        console.log("Ajax Request Id"+id);
        console.log(data);
        resolve();
      }
    });
  });
} 

function pushPromise(id)
{
  promises.Push(promises.pop().then(function(){
    return methodThatReturnsAPromise(id)}));
}


pushPromise(1);
pushPromise(3);
pushPromise(2);
0
Muthu Kumar
(async () => { 
  for(f of ['1.json','2.json','3.json']){
    var json = await $.getJSON(f);
    console.log(json)
 };
})()
  1. jQueryajax呼び出しで3つのjsonファイルをリクエストします
  2. 順番に(並列ではなく)処理し、待機します
  3. chrome/Firefox/Edgeで動作します(2018年1月30日現在)

詳細は [〜#〜] mdn [〜#〜]

0
Rm558

同期呼び出しは必ずしも遅いとは限りません。AJAX呼び出しが開いて、ソケットに投稿してから閉じるアプリがある場合、ソケットへの複数の呼び出しは、一部のソケットでしかできないため、意味がありません。単一の接続を処理します。この場合、データをキューに入れて、前のAJAX呼び出しが完了したときにのみ送信されるようにすると、データスループットが大幅に向上します。

0
tomski777