我如何让一个函数等到所有jQuery Ajax请求都在另一个函数中完成之后?
简而言之,在执行下一个请求之前,我需要等待所有Ajax请求完成。但是如何?
我如何让一个函数等到所有jQuery Ajax请求都在另一个函数中完成之后?
简而言之,在执行下一个请求之前,我需要等待所有Ajax请求完成。但是如何?
为了扩展Alex的答案,我有一个带有可变参数和Promise的示例。我想通过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/
您也可以使用async.js。
我认为它比$ .when更好,因为您可以合并各种不支持承诺的异步调用,例如超时,SqlLite调用等,而不仅仅是ajax请求。
jQuery允许您指定是否要使ajax请求异步。您可以简单地使ajax请求同步,然后其余代码直到它们返回才执行。
例如:
jQuery.ajax({
async: false,
//code
});
使用ajaxStop
事件。
例如,假设您在获取100个Ajax请求时收到了一条loading ...消息,并且希望在加载后隐藏该消息。
从jQuery 文档:
$("#loading").ajaxStop(function() {
$(this).hide();
});
请注意,它将等待该页面上完成的所有ajax请求。
如果您想等到ajax
文档中的所有请求都完成后,无论它们中有多少,都可以通过以下方式使用$ .ajaxStop事件:
$(document).ajaxStop(function () {
// 0 === $.active
});
在这种情况下,无需猜测将来可能会完成的应用程序中有多少个请求。在某些情况下,ajax请求可能是函数内部逻辑的一部分,这可能非常复杂(例如,调用其他函数),在这种情况下,您可能不会等到该函数用其整个逻辑完成后才开始,而不仅仅是等待ajax
部分完成。
$.ajaxStop
这里也可以绑定到HTML
您认为可能被修改的任何节点ajax
。
同样,此处理程序的目的是要知道何时没有活动 ajax
清除或重置某些内容。
PS:如果您不介意使用ES6
语法,则可以使用Promise.all
已知ajax
方法。例:
Promise.all([ajax1(), ajax2()]).then(() => {
// all requests finished successfully
}).catch(() => {
// all requests finished but one or more failed
})
这里有趣的一点是,它可以同时处理Promises
和$.ajax
请求。
这是展示最后一个的jsFiddle。
jQuery现在为此目的定义了一个when函数。
它接受任意数量的Deferred对象作为参数,并在它们全部解析后执行一个函数。
这意味着,如果您要发起(例如)四个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参数(即,您想使用可变数量的参数),它仍然可以完成,但是有点棘手。请参阅将Deferreds数组传递给$ .when()(以及在使用可变数量的参数进行故障排除时,可能还有jQuery。)。
如果您需要对ajax脚本等的失败模式进行更深入的控制,则可以保存由返回的对象.when()
-这是一个jQuery Promise对象,其中包含所有原始ajax查询。您可以调用.then()
或.fail()
在其上添加详细的成功/失败处理程序。
$.when
不适用于我,callback(x)
而不是return x
按此处所述工作:https : //stackoverflow.com/a/13455253/10357604