等到所有jQuery Ajax请求都完成了吗?

JavaScript

你的名字

2020-03-11

我如何让一个函数等到所有jQuery Ajax请求都在另一个函数中完成之后?

简而言之,在执行下一个请求之前,我需要等待所有Ajax请求完成。但是如何?

第730篇《等到所有jQuery Ajax请求都完成了吗?》来自Winter(https://github.com/aiyld/aiyld.github.io)的站点

7个回答
L番长 2020.03.11

$.when不适用于我,callback(x)而不是return x按此处所述工作:https : //stackoverflow.com/a/13455253/10357604

猪猪卡卡西 2020.03.11

为了扩展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/

JimAGil 2020.03.11

您也可以使用async.js

我认为它比$ .when更好,因为您可以合并各种不支持承诺的异步调用,例如超时,SqlLite调用等,而不仅仅是ajax请求。

奔跑的小象 2020.03.11

jQuery允许您指定是否要使ajax请求异步。您可以简单地使ajax请求同步,然后其余代码直到它们返回才执行。

例如:

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

使用ajaxStop事件。

例如,假设您在获取100个Ajax请求时收到了一条loading ...消息,并且希望在加载后隐藏该消息。

从jQuery 文档

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

请注意,它将等待该页面上完成的所有ajax请求。

JinJin宝儿 2020.03.11

如果您想等到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

LEY古一逆天 2020.03.11

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()在其上添加详细的成功/失败处理程序。

问题类别

JavaScript Ckeditor Python Webpack TypeScript Vue.js React.js ExpressJS KoaJS CSS Node.js HTML Django 单元测试 PHP Asp.net jQuery Bootstrap IOS Android