等待多个承诺被拒绝 [英] Wait for multiple promises to be rejected

查看:54
本文介绍了等待多个承诺被拒绝的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

做一些测试,我需要等待几个承诺被拒绝。

Doing some testing, I need to wait for a couple of promises to be rejected.

我知道我可以使用jQuery.when()来等待几个承诺得到解决。但是,如果其中一个承诺失败,那个方法就会拒绝主承诺。

I know that I can use jQuery.when() to wait for several promises tu be resolved. But that method reject the master promise as soon one of the promises fails.

我知道我所有的承诺都会失败,但无论如何我都需要等待它。我该怎么办?

I know that all my promises will fail, but I need to wait for it anyway. How can I do it?

在一种伪代码中我想做的是:

In a kind of pseudo-code what I want to do is:

var promise1 = connection.doCall();
var promise2 = connection.doCall();

$.when([promise1, promise2]).allOfThemFail(function() {
    assertThatSomeProcessWasDoneOnlyOnce()
});


推荐答案

使用Bluebird promise库,你可以使用 Promise.settle()等待所有承诺被解决(例如履行或拒绝),然后您可以简单地查询列表以查看它们是否全部被拒绝。

Using the Bluebird promise library, you can use Promise.settle() which waits for all the promises to be settled (e.g. fulfilled or rejected) and then you can simply query the list to see if they were all rejected.

var p1 = connection.doCall();
var p2 = connection.doCall();
Promise.settle([p1, p2]).then(function(results) {
    var allRejected = results.every(function(item) {
        return item.isRejected();
    });
    // act on allRejected here
});






这是一个特定于jQuery的<$ c版本$ c>结算():

(function() {    

    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;
            }
        };
    }

    // 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);
            // Now we know for sure that p is a promise
            // 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);
        });
    }

})();

而且,你会像Bluebird解决方案一样使用它:

And, you would use this similarly to the Bluebird solution:

var p1 = connection.doCall();
var p2 = connection.doCall();
$.settle([p1, p2]).then(function(results) {
    var allRejected = results.every(function(item) {
        return item.isRejected();
    });
    // act on allRejected here
});






而且,这是 sett()使用标准的ES6承诺从头开始构建函数构建。它返回一个单一的promise,当所有其他promises完成时解析(无论它们的最终状态如何)。这个超级承诺的解析结果是一个 PromiseInspection 对象的数组,您可以在其中查询 isFulfilled() isRejected()并且可以获得 .value() .reason()


And, here's a settle() type function build from scratch using standard ES6 promises. It returns a single promise that is resolved when all the other promises have finished (regardless of their final state). The resolved result of this uber promise is an array of PromiseInspection objects where you can query isFulfilled() or isRejected() and can obtain the .value() or .reason().

Promise.isPromise = function(p) {
    return p && (typeof p === "object" || typeof p === "function") && typeof p.then === "function";
}

// ES6 version of settle
Promise.settle = function(promises) {
    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;
            }
        };
    }

    return Promise.all(promises.map(function(p) {
        // make sure any values are wrapped in a promise
        if (!Promise.isPromise(p)) {
            p = Promise.resolve(p);
        }
        return p.then(function(val) {
            return new PromiseInspection(true, val);
        }, function(err) {
            return new PromiseInspection(false, val);
        });
    }));
}

而且,你会像上面一样使用它:

And, you would use this similarly as above:

var p1 = connection.doCall();
var p2 = connection.doCall();
Promise.settle([p1, p2]).then(function(results) {
    var allRejected = results.every(function(item) {
        return item.isRejected();
    });
    // act on allRejected here
});

这篇关于等待多个承诺被拒绝的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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