使用jQuery并行执行多个promise后等待完成

Wait for completion after multiple promises in parallel using jQuery

本文关键字:等待 promise jQuery 并行执行 使用      更新时间:2024-05-14

我想使用jquery:的延迟/承诺实现对多个异步ajax请求进行排队

function doSomething() {
    console.log('doSomething')};
function makeMultiAjaxRequests1() {
    console.log('makeMultiAjaxRequests1')};
function makeMultiAjaxRequests2() {
    console.log('makeMultiAjaxRequests2')};
var step1 = function () { 
    var promise = new $.Deferred().promise();   
    makeMultiAjaxRequests1(); 
    return promise; }
var step2 = function () {
    var promise = new $.Deferred().promise();
    makeMultiAjaxRequests2();
    return promise; } 
step1()
   .then(step2())
   .done(doSomething());
$.when(step1(), 
       step2())
   .done(function () {
    doSomething();
});

这是小提琴的链接。所以我的问题是:

在步骤1和步骤2并行执行的模式中,代码不会到达最后一个处理程序函数。为什么?

您需要在步骤1和步骤2中解析deferred对象

试试这个

function doSomething() {
    console.log('doSomething')};
function makeMultiAjaxRequests1(deferred) {
    console.log('makeMultiAjaxRequests1')
    deferred.resolve()};
function makeMultiAjaxRequests2(deferred) {
    console.log('makeMultiAjaxRequests2')
    deferred.resolve()};
var step1 = function () { 
    var deferred = new $.Deferred();   
    makeMultiAjaxRequests1(deferred); 
    return deferred; }
var step2 = function () {
    var deferred = new $.Deferred();
    makeMultiAjaxRequests2(deferred);
    return deferred; } 
step1().then(step2).done(doSomething);
$.when(step1(), step2()).done(function () {
    doSomething();
});

@Daiwei给出了一个很好的答案。

一个常见的要点是https://gist.github.com/sergio-fry/3917217由塞尔吉奥·弗莱。

如果您想要一种更动态的方法,在这种方法中,您事先不知道有多少个参数是并行运行的,下面是JQuery(1.10+)的一个很好的扩展示例:

$.whenAll = function (deferreds) {
    function isPromise(fn) {
        return fn && typeof fn.then === 'function' &&
            String($.Deferred().then) === String(fn.then);
    }
    var d = $.Deferred(),
        keys = Object.keys(deferreds),
        args = keys.map(function (k) {
            return $.Deferred(function (d) {
                var fn = deferreds[k];
                (isPromise(fn) ? fn : $.Deferred(fn))
                    .done(d.resolve)
                    .fail(function (err) { d.reject(err, k); })
                ;
            });
        });
    $.when.apply(this, args)
        .done(function () {
            var resObj = {},
                resArgs = Array.prototype.slice.call(arguments);
            resArgs.forEach(function (v, i) { resObj[keys[i]] = v; });
            d.resolve(resObj);
        })
        .fail(d.reject);
    return d;
};

请参阅动态实时示例中的代码:

http://jsbin.com/nuxuciwabu/edit?js,控制台

如果你给它一个它可以实际访问的URL,它确实会访问你的done函数(在jsfiddle的情况下,也就是说/echo/html/:http://jsfiddle.net/LnaPt/2/

基本上,你只需要这样做:

var promise = $.ajax({
    type: "GET",
    url: "/echo/html/",   //<-- instead of google     
}).promise();