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?
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?
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/
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>
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.
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>
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.
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 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.
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