jQuery-延迟等待一系列Ajax请求以完成甚至失败 [英] jQuery - Deferreds waiting for an array of ajax requests to complete even failures

查看:102
本文介绍了jQuery-延迟等待一系列Ajax请求以完成甚至失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在完成许多ajax请求之后,无论它们成功还是出错,如何执行函数?

How can execute a function after a number of ajax requests have all completed regardless of whether they succeeded or error-ed out?

我一直在尝试使用 $。when.apply(this,array)传递一组延迟的jqXHR对象。但是,就像文档中所说的那样

I've been trying to use $.when.apply(this, array) to pass an array of deferred jqXHR objects. However just like the docs say


在多次递延的情况下,其中一个递延者被拒绝,jQuery。当立即>触发failCallbacks时为其主人Deferred。请注意,此时仍可能无法解决某些Deferred。

In the multiple-Deferreds case where one of the Deferreds is rejected, jQuery.when immediately >fires the failCallbacks for its master Deferred. Note that some of the Deferreds may still be >unresolved at that point.

如何利用jQuery延迟对象始终等待所有阿贾克斯电话完成?

How can leverage jQuery deferred objects to always wait for all the ajax calls to finish?

也许我应该创建自己的将所有其他延迟项都包含在内的延迟项?如果是这样,我不太清楚如何设置它。

Maybe I should create my own deferred that will wrap all the other deferreds? If so I'm not quite clear how to set that up.

推荐答案

本着Promise规范的发展思路为了将来使用 PromiseInspection 对象,这是一个jQuery附加功能,可告诉您何时完成所有承诺,无论是兑现还是拒绝:

In the spirit of how the Promise specification is likely going for the future with a PromiseInspection object, here's a jQuery add-on function that tells you when all promises are done, whether fulfilled or rejected:

(function() {    
    // pass either multiple promises as separate arguments or an array of promises
    $.settle = function(p1) {
        var args;
        if (Array.isArray(p1)) {
              args = p1;
        } else {
            args = Array.prototype.slice.call(arguments);
        }

        return $.when.apply($, args.map(function(p) {
            // make sure p is a promise (it could be just a value)
            p = wrapInPromise(p);
            // Make sure that the returned promise here is always resolved with a PromiseInspection object, never rejected
            return p.then(function(val) {
                return new PromiseInspection(true, val);
            }, function(reason) {
                // Convert rejected promise into resolved promise by returning a resolved promised
                // One could just return the promiseInspection object directly if jQuery was
                // Promise spec compliant, but jQuery 1.x and 2.x are not so we have to take this extra step
                return wrapInPromise(new PromiseInspection(false, reason));
            });
        })).then(function() {
              // return an array of results which is just more convenient to work with
              // than the separate arguments that $.when() would normally return
            return Array.prototype.slice.call(arguments);
        });
    }

    // utility functions and objects
    function isPromise(p) {
        return p && (typeof p === "object" || typeof p === "function") && typeof p.then === "function";
    }

    function wrapInPromise(p) {
        if (!isPromise(p)) {
            p = $.Deferred().resolve(p);
        }
        return p;
    }

    function PromiseInspection(fulfilled, val) {
        return {
            isFulfilled: function() {
                return fulfilled;
            }, isRejected: function() {
                return !fulfilled;
            }, isPending: function() {
                // PromiseInspection objects created here are never pending
                return false;
            }, value: function() {
                if (!fulfilled) {
                    throw new Error("Can't call .value() on a promise that is not fulfilled");
                }
                return val;
            }, reason: function() {
                if (fulfilled) {
                    throw new Error("Can't call .reason() on a promise that is fulfilled");
                }
                return val;
            }
        };
    }
})();

然后,您可以像这样使用它:

Then, you can use it like this:

$.settle(promiseArray).then(function(inspectionArray) {
    inspectionArray.forEach(function(pi) {
        if (pi.isFulfilled()) {
            // pi.value() is the value of the fulfilled promise
        } else {
            // pi.reason() is the reason for the rejection
        }
    });
});

请记住 $。settle()将始终满足(从不拒绝),并且实现的值是一个 PromiseInspection 对象的数组,您可以询问每个对象以查看它是被实现还是被拒绝,然后获取对应的对象价值或原因。有关示例用法,请参见下面的演示:

Keep in mind that $.settle() will always fulfill (never reject) and the fulfilled value is an array of PromiseInspection objects and you can interrogate each one to see if it was fulfilled or rejected and then fetch the corresponding value or reason. See the demo below for example usage:

正在运行的演示: https://jsfiddle.net/jfriend00/y0gjs31r/

这篇关于jQuery-延迟等待一系列Ajax请求以完成甚至失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆