すべてのjQuery Ajaxリクエストが完了するまで待ちますか?


675

すべてのjQuery Ajaxリクエストが別の関数内で完了するまで関数を待機させるにはどうすればよいですか?

つまり、Ajaxリクエストがすべて完了するのを待ってから、次のリクエストを実行する必要があります。しかし、どうやって?


元のajaxリクエストをどのように呼び出していますか?
NakedBrunch

2
「完了」とはどういう意味ですか?「すべてのリクエストが正常に終了したか、終了していない」(解決または拒否された)と理解しています。しかし、「すべてのリクエストが正常に終了した」ことを意味するかもしれません(解決済み)。api.jquery.com/category/deferred-objectの
Adrien Be

回答:


911

jQueryは、この目的のためのwhen関数を定義するようになりまし

任意の数のDeferredオブジェクトを引数として受け入れ、それらがすべて解決されると関数を実行します。

つまり、(たとえば)4つのajaxリクエストを開始し、それらが完了したときにアクションを実行する場合は、次のようなことを行うことができます。

$.when(ajax1(), ajax2(), ajax3(), ajax4()).done(function(a1, a2, a3, a4){
    // the code here will be executed when all four ajax requests resolve.
    // a1, a2, a3 and a4 are lists of length 3 containing the response text,
    // status, and jqXHR object for each of the four ajax calls respectively.
});

function ajax1() {
    // NOTE:  This function must return the value 
    //        from calling the $.ajax() method.
    return $.ajax({
        url: "someUrl",
        dataType: "json",
        data:  yourJsonData,            
        ...
    });
}

私の意見では、これは簡潔で明確な構文を作成し、ページの開発中に不要な副作用を引き起こす可能性のあるajaxStartやajaxStopなどのグローバル変数の関与を回避します。

待機する必要があるajax引数の数が事前にわからない場合(つまり、可変数の引数を使用したい場合)は、まだ実行できますが、少しトリッキーです。$ .when()へのDeferredの配列の受け渡し(および可変数の引数を使用したトラブルシューティングのjQuery .whenを参照)を参照してください。

ajaxスクリプトなどの失敗モードをより詳細に制御する必要がある場合は、返されるオブジェクトを保存できます。これは、元のすべてのajaxクエリを含む.when()jQuery Promiseオブジェクトです。.then()または.fail()を呼び出して、詳細な成功/失敗ハンドラを追加できます。


46
これはシンプルで効率的で優れた動作をするため、正解としてマークする必要があります。また、はだけでなく、より便利なメソッドを持つオブジェクトを$.when返すことにも注意してください。たとえば、メソッドを使用すると、両方のリクエストが成功した場合、または少なくとも一方が失敗した場合に対応できます。Promise.done.then(onSuccess, onFailure)
スケーリー

2
リクエストajax1..4を配列にまとめてそれを渡すことは可能ですか?
andig 2013

33
failケースに注意してください。とは異なりdonefail最初に発砲するとすぐに失敗し、残りの遅延オブジェクトは無視されます。
Ryan Mohr 2013

1
@skalee onFailure関数を添付できることを強調してくれてありがとう。OPの質問へのコメントで指摘したように、彼は「完了」の意味をより正確に示したいと思うかもしれません。「ライアン・モール」もあるという事実については非常に良い点を持っていなかったfail振る舞いが異なっなどdoneについて、さらにいくつかの読み取りが行われるようにPromises、私は推測するhtml5rocks.com/en/tutorials/es6/promisesを
エイドリアンはして

1
whenメソッドや一般的な約束を人々に公開するのは素晴らしいことですが、これは最良の答えではないと思います。これらのajax関数のいずれかが将来的に別のajaxリクエストを作成し、その新しいプロミスをチェーンに正しく統合しない場合...これらのリクエストはこの手法を回避します。たとえば、ajaxのカートへの追加動作に使用しているShopifyライブラリを変更せずにこの手法を使用することはできません。これは、「約束のある」方法で記述されておらず、作成するxhrオブジェクトを返さないためです。これは理にかなっていますか?それでも素晴らしい答えです!
ジギー

292

ドキュメント内のすべての ajaxリクエストがいつ終了したかを知りたい場合は、リクエストの数に関係なく、次のように$ .ajaxStopイベントを使用します。

$(document).ajaxStop(function () {
  // 0 === $.active
});

この場合、アプリケーションで発生している将来の要求の数を推測する必要も、関数の複雑なロジックを調べたり、HTTP(S)要求を実行している関数を見つける必要もありません。

$.ajaxStopここでHTMLrequstによって変更される可能性があると思われる任意のノードにバインドすることもできます。


更新:構文
にこだわりたい場合は、既知のメソッドにPromise.allES使用できます。ajax

Promise.all([ajax1(), ajax2()]).then(() => {
  // all requests finished successfully
}).catch(() => {
  // all requests finished but one or more failed
})

ここで興味深い点は、Promises$.ajaxリクエストの両方で機能することです。

これがjsFiddleのデモです。


更新2:async / await構文
を使用したさらに新しいバージョン:

try {
  const results = await Promise.all([ajax1(), ajax2()])
  // do other actions
} catch(ex) { }

16
+1 匿名のコールバック/クロージャーでサードパーティのスクリプトを処理する必要がある場合に備えて、他の回答よりもはるかに優れています。
カイザー2013

5
@kaiser有効なポイントですが、質問が求めていたものではありません。すべてのAJAX呼び出しが戻るのを待ちたくない場合は、あまり良くありません。質問は、自分で行ったAOP呼び出しの待機に関するものです(OPが書いたように、別の関数内で呼び出されます)。他のいくつかのコードが、待機したくない別のAJAX呼び出しを行った可能性があります。
ファンメンデス

6
when()ソリューションと比較すると、ajax呼び出しの数が不明な場合でも機能するという利点があります。
Alexis Dufrenoy 14年

5
when()ソリューションと比較すると、ドキュメント全体のグローバル状態を共有するため、他のコンポーネントとうまく連携しないことには大きな欠点があります。長時間のポーリングが継続的に行われている場合、それが起動することさえありません。
Bergi 14

3
あなたは正しい@AdrienBeじゃない、ajaxStopは関係なく、彼らがこれを見て私の言葉の証明として、成功しないか、していないすべてのAJAX要求を処理jsfiddle.net/36votxba/2
アルセンKhachaturyan

32

私が見つかりました。良い答えによってgnarf私が探していたものを正確に私の自己を:)

jQuery ajaxQueue

//This handles the queues    
(function($) {

  var ajaxQueue = $({});

  $.ajaxQueue = function(ajaxOpts) {

    var oldComplete = ajaxOpts.complete;

    ajaxQueue.queue(function(next) {

      ajaxOpts.complete = function() {
        if (oldComplete) oldComplete.apply(this, arguments);

        next();
      };

      $.ajax(ajaxOpts);
    });
  };

})(jQuery);

次に、次のようにajaxリクエストをキューに追加できます。

$.ajaxQueue({
        url: 'page.php',
        data: {id: 1},
        type: 'POST',
        success: function(data) {
            $('#status').html(data);
        }
    });

37
この回答に適切な帰属を付けるのを忘れているようです。追加しました。
Tim Post

21

ajaxStopイベントを使用します。

たとえば、100個のAjaxリクエストをフェッチしているときに、loading ...メッセージがあり、一度ロードされたメッセージを非表示にしたいとします。

jQuery docから:

$("#loading").ajaxStop(function() {
  $(this).hide();
});

そのページで実行されるすべてのajaxリクエストを待つことに注意してください。


5
これは、ページに他のAJAXリクエストがないことを前提としており、あまり適切な仮定ではありません
Juan Mendes

jQuery 1.8以降、.ajaxStop()メソッドはドキュメントにのみアタッチする必要があります。
Geomorillo、2014

1
私が間違っている場合は修正してください。ただし、これによりプロジェクトが「古い学校のWebフォーム」サイトに変換されませんか?つまり、あなたのページ全体がリクエストを続行する前に待たなければならない場合、そもそもajaxリクエストの要点は何ですか?
BillRuhl、2015年

私たちの場合、@ BillRuhlでは、jqueryコレクションをループして新しいものを構築しており、レイアウトの調整を行う前に、完了時にコレクション全体について知る必要があります。特に異常なケースではないようです。他のajaxの要素がたくさん処理されているとしたら悪いのですが、ここではそうではありません。
EON

21

注:上記の回答は、この回答が書かれた時点では存在しなかった機能を使用しています。私は使用をお勧めしますjQuery.when()これらのアプローチの代わりにするますが、答えは歴史的な目的のために残しておきます。

-

実装方法はコードに依存しますが、おそらく単純なカウントセマフォでうまくいくでしょう。簡単な例は次のようなものです...

var semaphore  = 0,     // counting semaphore for ajax requests
    all_queued = false; // bool indicator to account for instances where the first request might finish before the second even starts

semaphore++;
$.get('ajax/test1.html', function(data) {
    semaphore--;
    if (all_queued && semaphore === 0) {
        // process your custom stuff here
    }
});

semaphore++;
$.get('ajax/test2.html', function(data) {
    semaphore--;
    if (all_queued && semaphore === 0) {
        // process your custom stuff here
    }
});

semaphore++;
$.get('ajax/test3.html', function(data) {
    semaphore--;
    if (all_queued && semaphore === 0) {
        // process your custom stuff here
    }
});

semaphore++;
$.get('ajax/test4.html', function(data) {
    semaphore--;
    if (all_queued && semaphore === 0) {
        // process your custom stuff here
    }
});

// now that all ajax requests are queued up, switch the bool to indicate it
all_queued = true;

これを{async:false}のように動作させたいが、ブラウザをロックしたくない場合は、jQueryキューを使用して同じことを実行できます。

var $queue = $("<div/>");
$queue.queue(function(){
    $.get('ajax/test1.html', function(data) {
        $queue.dequeue();
    });
}).queue(function(){
    $.get('ajax/test2.html', function(data) {
        $queue.dequeue();
    });
}).queue(function(){
    $.get('ajax/test3.html', function(data) {
        $queue.dequeue();
    });
}).queue(function(){
    $.get('ajax/test4.html', function(data) {
        $queue.dequeue();
    });
});

10
これは、些細な問題を過度に複雑にするようです。
Chris

2
それほど複雑ではありません。セマフォのカウントは、CSの一般的なメカニズムです。ただし、jQueryキューを使用する例は、自分でセマフォを実装しなくても機能します。
BBonifield 2010

1
セマフォカウンターに問題はありませんが、結果のコールバックを処理する4つの関数を使用するという考えには問題があります。最初に関数を定義してから、各でその関数を参照する必要があります.get()。そうすれば、少なくともそのコードを複製することはできません。それだけでなく、function(){}毎回宣言すると毎回メモリが割り当てられます!静的に定義された関数を呼び出すことができる場合は、むしろ悪い習慣です。
Alexis Wilke、2015年

1
@AlexisWilkeこれは4.5年前の回答であり、セマフォとキューがどのように機能するかの例となることを意図していた。あなたはこれについて少し考えすぎているので、私はポイントを獲得するための資本化が必要だとは思いません。
BBonifield、2015年

2
ええと...私はあなたに-1を与えたのは私ではありません... しかし、人々はそれらを見つけ続けており、私の知る限り、今日でもそれらを利用する可能性のある人々に情報を提供することは禁止されていません。
Alexis Wilke、2015年

8

JavaScriptはイベントベースであるため、フック/コールバックを設定するのではなく、決して待機しないでください

あなたはおそらくjquery.ajaxの成功/完了メソッドを使用することができます

または、.ajaxCompleteを使用できます。

$('.log').ajaxComplete(function(e, xhr, settings) {
  if (settings.url == 'ajax/test.html') {
    $(this).text('Triggered ajaxComplete handler.');
    //and you can do whatever other processing here, including calling another function...
  }
});

ただし、より正確にするには、ajaxリクエストの呼び出し方法の疑似コードを投稿する必要があります...


8

少しの回避策は次のようなものです:

// Define how many Ajax calls must be done
var ajaxCalls = 3;
var counter = 0;
var ajaxCallComplete = function() {
    counter++;
    if( counter >= ajaxCalls ) {
            // When all ajax calls has been done
        // Do something like hide waiting images, or any else function call
        $('*').css('cursor', 'auto');
    }
};

var loadPersons = function() {
        // Show waiting image, or something else
    $('*').css('cursor', 'wait');

    var url = global.ctx + '/loadPersons';
    $.getJSON(url, function(data) {
            // Fun things
    })
    .complete(function() { **ajaxCallComplete();** });
};

var loadCountries = function() {
    // Do things
    var url = global.ctx + '/loadCountries';
    $.getJSON(url, function(data) {
            // Travels
    })
    .complete(function() { **ajaxCallComplete();** });
};

var loadCities = function() {
    // Do things
    var url = global.ctx + '/loadCities';
    $.getJSON(url, function(data) {
            // Travels
    })
    .complete(function() { **ajaxCallComplete();** });
};

$(document).ready(function(){
    loadPersons();
    loadCountries();
    loadCities();
});

役に立つと思います...


他の答えの方が理解しやすいので技術的に優れていますが、私はこれが本当に好きです。いいね!
ジェイ14年

4

jQueryでは、ajaxリクエストを非同期にするかどうかを指定できます。ajaxリクエストを同期させるだけで、残りのコードはリクエストが戻るまで実行されません。

例えば:

jQuery.ajax({ 
    async: false,
    //code
});

42
注意すべきことの1つは、{async:false}を使用すると一時的にブラウザがロックされる可能性があることです。 api.jquery.com/jQuery.ajax
BBonifield 09/10/14

30
これは、標準のjQuery / Javascriptのプラクティスに反します。AJAXは常に非同期であると想定されています。代わりにjQuery.when()を使用してください。
SystemParadox

43
それはひどく悪い考えです!絶対にしないでください!ブロッキング=ユーザーのアクションにまったく応答しない、スクロールなどに応答しない!(また、async:falseはjQuery 1.8で廃止される予定です。)
skalee

5
特に、リクエストが失敗したり、予測できない理由(マーフィーの法則により、発生する可能性があります!)のために長時間かかる場合、これは通常、上で述べたようにブラウザーのロックが原因で本番用コードに悪い考えです。
Alex

27
これはひどく悪い考えです。この回答は使用しないでください。
Tauren

2

シンプルなものが必要な場合; 一度だけコールバック

        //multiple ajax calls above
        var callback = function () {
            if ($.active !== 0) {
                setTimeout(callback, '500');
                return;
            }
            //whatever you need to do here
            //...
        };
        callback();

4
無限ループが発生する可能性があります。
Diego Favero、2015

2
これは無限ループですか?いつ?AJAXが戻らないのはいつですか?
ジョナサン

2

また、async.jsを使用することもできます。

タイムアウト、SqlLite呼び出しなど、そのままではPromiseをサポートしておらず、Ajaxリクエストだけではないあらゆる種類の非同期呼び出しをマージできるため、$。whenよりも優れていると思います。


2

@BBonifieldの回答に基づいて、セマフォロジックがすべてのajax呼び出しに拡散しないように、ユーティリティ関数を作成しました。

untilAjax すべてのajaxCallが完了したときにコールバック関数を呼び出すユーティリティ関数です。

ajaxObjsajax設定オブジェクトの配列です[http://api.jquery.com/jQuery.ajax/]

fn コールバック関数です

function untilAjax(ajaxObjs, fn) {
  if (!ajaxObjs || !fn) {
    return;
  }
  var ajaxCount = ajaxObjs.length,
    succ = null;

  for (var i = 0; i < ajaxObjs.length; i++) { //append logic to invoke callback function once all the ajax calls are completed, in success handler.
    succ = ajaxObjs[i]['success'];
    ajaxObjs[i]['success'] = function(data) { //modified success handler
      if (succ) {
        succ(data);
      }
      ajaxCount--;
      if (ajaxCount == 0) {
        fn(); //modify statement suitably if you want 'this' keyword to refer to another object
      }
    };
    $.ajax(ajaxObjs[i]); //make ajax call
    succ = null;
  };

例:doSomething関数はを使用しuntilAjaxます。

function doSomething() {
  // variable declarations
  untilAjax([{
    url: 'url2',
    dataType: 'json',
    success: function(data) {
      //do something with success data
    }
  }, {
    url: 'url1',
    dataType: 'json',
    success: function(data) {
      //do something with success data
    }
  }, {
    url: 'url2',
    dataType: 'json',
    success: function(response) {
      //do something with success data
    }
  }], function() {
    // logic after all the calls are completed.
  });
}

2

最初から始める場合は、$。when()を使用することを強くお勧めします。

この質問には100万を超える回答がありますが、私の場合に役立つものはまだ見つかりませんでした。既存のコードベースを処理する必要があり、すでにいくつかのajax呼び出しを行っており、promiseの複雑さを導入したり、全体をやり直したりしたくないとしましょう。

私たちは、簡単にjQueryを利用することができ.data.onそして.trigger永遠以来のjQueryの一部となっている機能。

Codepen

私のソリューションの良いところは:

  • コールバックが正確に依存することは明らかです

  • 関数triggerNowOrOnLoadedは、データがすでにロードされているか、それともまだそれを待っているかを気にしません

  • 既存のコードにプラグインするのはとても簡単です

$(function() {

  // wait for posts to be loaded
  triggerNowOrOnLoaded("posts", function() {
    var $body = $("body");
    var posts = $body.data("posts");

    $body.append("<div>Posts: " + posts.length + "</div>");
  });


  // some ajax requests
  $.getJSON("https://jsonplaceholder.typicode.com/posts", function(data) {
    $("body").data("posts", data).trigger("posts");
  });

  // doesn't matter if the `triggerNowOrOnLoaded` is called after or before the actual requests 
  $.getJSON("https://jsonplaceholder.typicode.com/users", function(data) {
    $("body").data("users", data).trigger("users");
  });


  // wait for both types
  triggerNowOrOnLoaded(["posts", "users"], function() {
    var $body = $("body");
    var posts = $body.data("posts");
    var users = $body.data("users");

    $body.append("<div>Posts: " + posts.length + " and Users: " + users.length + "</div>");
  });

  // works even if everything has already loaded!
  setTimeout(function() {

    // triggers immediately since users have been already loaded
    triggerNowOrOnLoaded("users", function() {
      var $body = $("body");
      var users = $body.data("users");

      $body.append("<div>Delayed Users: " + users.length + "</div>");
    });

  }, 2000); // 2 seconds

});

// helper function
function triggerNowOrOnLoaded(types, callback) {
  types = $.isArray(types) ? types : [types];

  var $body = $("body");

  var waitForTypes = [];
  $.each(types, function(i, type) {

    if (typeof $body.data(type) === 'undefined') {
      waitForTypes.push(type);
    }
  });

  var isDataReady = waitForTypes.length === 0;
  if (isDataReady) {
    callback();
    return;
  }

  // wait for the last type and run this function again for the rest of the types
  var waitFor = waitForTypes.pop();
  $body.on(waitFor, function() {
    // remove event handler - we only want the stuff triggered once
    $body.off(waitFor);

    triggerNowOrOnLoaded(waitForTypes, callback);
  });
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<body>Hi!</body>


2

すべてのajaxロードが完了したときにサイズチェックを使用しています

function get_ajax(link, data, callback) {
    $.ajax({
        url: link,
        type: "GET",
        data: data,
        dataType: "json",
        success: function (data, status, jqXHR) {
            callback(jqXHR.status, data)
        },
        error: function (jqXHR, status, err) {
            callback(jqXHR.status, jqXHR);
        },
        complete: function (jqXHR, status) {
        }
    })
}

function run_list_ajax(callback){
    var size=0;
    var max= 10;
    for (let index = 0; index < max; index++) {
        var link = 'http://api.jquery.com/ajaxStop/';
        var data={i:index}
        get_ajax(link,data,function(status, data){
            console.log(index)
            if(size>max-2){
                callback('done')
            }
            size++
            
        })
    }
}

run_list_ajax(function(info){
    console.log(info)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>


あなたの例に賛成です。
MarwaAhmad

2

アレックスの答えをさらに詳しく説明するために、可変引数とプロミスを使用した例を示します。画像をajax経由でロードし、すべてロードした後にページに表示したいと思っていました。

そのために、私は以下を使用しました:

let urlCreator = window.URL || window.webkitURL;

// Helper function for making ajax requests
let fetch = function(url) {
    return $.ajax({
        type: "get",
        xhrFields: {
            responseType: "blob"
        },
        url: url,
    });
};

// Map the array of urls to an array of ajax requests
let urls = ["https://placekitten.com/200/250", "https://placekitten.com/300/250"];
let files = urls.map(url => fetch(url));

// Use the spread operator to wait for all requests
$.when(...files).then(function() {
    // If we have multiple urls, then loop through
    if(urls.length > 1) {
        // Create image urls and tags for each result
        Array.from(arguments).forEach(data => {
            let imageUrl = urlCreator.createObjectURL(data[0]);
            let img = `<img src=${imageUrl}>`;
            $("#image_container").append(img);
        });
    }
    else {
        // Create image source and tag for result
        let imageUrl = urlCreator.createObjectURL(arguments[0]);
        let img = `<img src=${imageUrl}>`;
        $("#image_container").append(img);
    }
});

単一または複数のURLで機能するように更新:https : //jsfiddle.net/euypj5w9/


2

他の回答が述べたようにajaxStop()、すべてのajaxリクエストが完了するまで待つために使用できます。

$(document).ajaxStop(function() {
     // This function will be triggered every time any ajax request is requested and completed
});

特定のajax()リクエストに対してそれをしたい場合はcomplete()、特定のajaxリクエスト内のメソッドを使用するのが最善です。

$.ajax({
    type: "POST",
    url: "someUrl",
    success: function(data) {
        // This function will be triggered when ajax returns a 200 status code (success)
    },
    complete: function() {
        // This function will be triggered always, when ajax request is completed, even it fails/returns other status code
    },
    error: function() {
        // This will be triggered when ajax request fail.
    }
});


しかし、いくつかの特定のajaxリクエストが完了するまで待つ必要がある場合はどうでしょうか。すばらしいjavascriptの約束を使用して、待ちたいこれらのajaxが完了するまで待ちます。短く簡単で読みやすい例を作成して、promiseがajaxでどのように機能するかを示しました。
次の例をご覧くださいsetTimeout例を明確にするために使用しました。

// Note:
// resolve() is used to mark the promise as resolved
// reject() is used to mark the promise as rejected

$(document).ready(function() {
    $("button").on("click", function() {

        var ajax1 = new Promise((resolve, reject) => {
            $.ajax({
                type: "GET",
                url: "https://miro.medium.com/max/1200/0*UEtwA2ask7vQYW06.png",
                xhrFields: { responseType: 'blob'},
                success: function(data) {
                    setTimeout(function() {
                        $('#image1').attr("src", window.URL.createObjectURL(data));
                        resolve(" Promise ajax1 resolved");
                    }, 1000);
                },
                error: function() {
                    reject(" Promise ajax1 rejected");
                },
            });
        });

        var ajax2 = new Promise((resolve, reject) => {
            $.ajax({
                type: "GET",
                url: "https://cdn1.iconfinder.com/data/icons/social-media-vol-1-1/24/_github-512.png",
                xhrFields: { responseType: 'blob' },
                success: function(data) {
                    setTimeout(function() {
                         $('#image2').attr("src", window.URL.createObjectURL(data));
                         resolve(" Promise ajax2 resolved");
                    }, 1500);
                },
                error: function() {
                    reject(" Promise ajax2 rejected");
                },
            });
        });

        var ajax3 = new Promise((resolve, reject) => {
            $.ajax({
                type: "GET",
                url: "https://miro.medium.com/max/632/1*LUfpOf7teWvPdIPTBmYciA.png",
                xhrFields: { responseType: 'blob' },
                success: function(data) {
                    setTimeout(function() {
                         $('#image3').attr("src", window.URL.createObjectURL(data));
                         resolve(" Promise ajax3 resolved");
                    }, 2000);
                },
                error: function() {
                    reject(" Promise ajax3 rejected");
                },
            });
        });
        
        Promise.all([ajax1, ajax2, ajax3]).then(values => {
            console.log("We waited until ajax ended: " + values);
            console.log("My few ajax ended, lets do some things!!")
        }, reason => {
            console.log("Promises failed: " + reason);
        });
        
        // Or if you want wait for them individually do it like this
        // ajax1.then(values => {
        //    console.log("Promise 1 resolved: " + values)
        // }, reason => {
        //     console.log("Promise 1 failed: " + reason)
        // });
    });

});
img {
  max-width: 200px;
  max-height: 100px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button>Make AJAX request</button>
<div id="newContent">
    <img id="image1" src="">
    <img id="image2" src="">
    <img id="image3" src="">
</div>


0

私はそれを使って簡単な方法を見つけました shift()

function waitReq(id)
{
  jQuery.ajax(
  {
    type: 'POST',
    url: ajaxurl,
    data:
    {
      "page": id
    },
    success: function(resp)
    {
      ...........
      // check array length if not "0" continue to use next array value
      if(ids.length)
      {
        waitReq(ids.shift()); // 2
      )
    },
    error: function(resp)
    {
      ....................
      if(ids.length)
      {
        waitReq(ids.shift());
      )
    }
  });
}

var ids = [1, 2, 3, 4, 5];    
// shift() = delete first array value (then print)
waitReq(ids.shift()); // print 1

0

私の解決策は次のとおりです

var request;
...
'services': {
  'GetAddressBookData': function() {
    //This is the primary service that loads all addressbook records 
    request = $.ajax({
      type: "POST",
      url: "Default.aspx/GetAddressBook",
      contentType: "application/json;",
      dataType: "json"
    });
  },

  ...

  'apps': {
    'AddressBook': {
      'data': "",
      'Start': function() {
          ...services.GetAddressBookData();
          request.done(function(response) {
            trace("ajax successful");
            ..apps.AddressBook.data = response['d'];
            ...apps.AddressBook.Filter();
          });
          request.fail(function(xhr, textStatus, errorThrown) {
            trace("ajax failed - " + errorThrown);
          });

かなりうまくいきました。これを行うためにさまざまな方法を試しましたが、これが最も簡単で最も再利用可能な方法であることがわかりました。それが役に立てば幸い


0

私の解決策を見てください:

1.この関数(および変数)をJavaScriptファイルに挿入します。

var runFunctionQueue_callback;

function runFunctionQueue(f, index, callback) {

  var next_index = index + 1

  if (callback !== undefined) runFunctionQueue_callback = callback;

  if (f[next_index] !== undefined) {
    console.log(index + ' Next function avalaible -> ' + next_index);
    $.ajax({
      type: 'GET',
      url: f[index].file,
      data: (f[index].data),
      complete: function() {
        runFunctionQueue(f, next_index);
      }
    });
  } else {
    console.log(index + ' Last function');
    $.ajax({
      type: 'GET',
      url: f[index].file,
      data: (f[index].data),
      async: false,
      complete: runFunctionQueue_callback
    });
  }
}

2.次のように、リクエストを含む配列を作成します。

var f = [
           {file: 'file_path', data: {action: 'action', data: 'any_data}},
           {file: 'file_path', data: {action: 'action', data: 'any_data}},
           {file: 'file_path', data: {action: 'action', data: 'any_data}},
           {file: 'file_path', data: {action: 'action', data: 'any_data}}
        ];

3.コールバック関数を作成します。

function Function_callback() {
  alert('done');
}

4.パラメータを指定してrunFunctionQueue関数を呼び出します。

runFunctionQueue(f, 0, QuestionInsert_callback);
// first parameter: array with requests data
// second parameter: start from first request
// third parameter: the callback function


-4

この方法を試してください。javaスクリプト関数内でループを作成して、ajax呼び出しが終了するまで待機します。

function getLabelById(id)
{
    var label = '';
    var done = false;
    $.ajax({
       cache: false,
       url: "YourMvcActionUrl",
       type: "GET",
       dataType: "json",
       async: false,
       error: function (result) {
         label='undefined';
         done = true;
        },
       success: function (result) {
            label = result.Message;
            done = true;
        }
     });

   //A loop to check done if ajax call is done.
   while (!done)
   {
      setTimeout(function(){ },500); // take a sleep.
   }

    return label;
}

1
あなたsetTimeout()はしませんtake a sleep。この場合、donetrueになるまですべてのタブをブロックするだけです。
Alexis Wilke、2015年

1
私はそれが「すべてのjQuery Ajax要求が完了するまで待つ」というこのトピックだと思います。
ChinaHelloWorld 2015年

1
このコードをテストしましたか?私の期待はdone、whileループが実行されている間は決して真実ではないということです。whileループが実行されている場合、イベントループは続行できないため、ajax成功へのコールバックは実行されません。
Kevin B
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.