761 Stimmen

Warten, bis alle jQuery Ajax-Anfragen erledigt sind?

Wie mache ich eine Funktion warten, bis alle jQuery Ajax-Anforderungen innerhalb einer anderen Funktion fertig sind?

Kurz gesagt, ich muss warten, bis alle Ajax-Anfragen erledigt sind, bevor ich die nächste ausführe. Aber wie?

0 Stimmen

Wie rufen Sie Ihre ursprünglichen Ajax-Anfragen auf?

2 Stimmen

Was meinen Sie mit "erledigt"? Ich verstehe es so, dass alle Anfragen entweder erfolgreich oder nicht erfolgreich abgeschlossen wurden (gelöst oder abgelehnt). Vielleicht meinen Sie aber auch "alle Anfragen wurden erfolgreich abgeschlossen" (gelöst). siehe alle Variationen in api.jquery.com/category/deferred-object

2voto

GammaGames Punkte 1462

Um Alex' Antwort zu ergänzen, habe ich ein Beispiel mit variablen Argumenten und Versprechen. Ich wollte Bilder über Ajax laden und sie auf der Seite anzeigen, nachdem sie alle geladen wurden.

Dazu habe ich das Folgende verwendet:

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);
    }
});

Aktualisiert, um entweder für einzelne oder mehrere Urls zu funktionieren: https://jsfiddle.net/euypj5w9/

2voto

tranchau Punkte 83

Ich verwende die Größenprüfung, wenn alle Ajax-Ladevorgänge abgeschlossen sind.

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>

2voto

cilf Punkte 642

Ich empfehle dringend die Verwendung von $.when() wenn Sie ganz neu anfangen.

Obwohl es auf diese Frage mehr als eine Million Antworten gibt, habe ich immer noch nichts Nützliches für meinen Fall gefunden. Nehmen wir an, Sie haben mit einer bestehenden Codebasis zu tun, bereits einige Ajax-Aufrufe und wollen nicht die Komplexität der Versprechungen einführen und/oder die ganze Sache neu machen.

Wir können die Vorteile von jQuery leicht nutzen .data , .on y .trigger Funktionen, die seit jeher ein Teil von jQuery sind.

Codepen

Das Gute an meiner Lösung ist:

  • es ist offensichtlich, wovon der Rückruf genau abhängt

  • die Funktion triggerNowOrOnLoaded kümmert sich nicht darum, ob die Daten bereits geladen wurden oder ob wir noch auf sie warten

  • es ist super einfach, ihn in einen bestehenden Code einzubauen

    $(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>

2voto

George Mavritsakis Punkte 6725

Sie können auch Folgendes verwenden async.js .

Ich denke, seine besser als $.when, weil Sie alle Arten von asynchronen Aufruf, der nicht unterstützt Versprechen aus der Box wie Timeouts, SqlLite Anrufe usw. und nicht nur Ajax-Anforderungen zusammenführen können.

2voto

Auf der Grundlage von @BBonifield Antwort, schrieb ich eine Utility-Funktion, so dass Semaphore Logik nicht in alle Ajax-Aufrufe verteilt ist.

untilAjax ist die Utility-Funktion, die eine Callback-Funktion aufruft, wenn alle ajaxCalls abgeschlossen sind.

ajaxObjs ist ein Array von Ajax-Einstellungsobjekten [http://api.jquery.com/jQuery.ajax/] .

fn ist eine Rückruf-Funktion

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;
  };

Beispiel: doSomething Funktion verwendet 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.
  });
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X