使用 Bluebird Promise 库,您可以使用Promise.settle()
它等待所有承诺都被解决(例如履行或拒绝),然后您可以简单地查询列表以查看它们是否全部被拒绝。
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 特定版本settle()
:
(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 解决方案一样使用它:
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
});
而且,这是一个settle()
使用标准 ES6 Promise 从头开始构建类型函数。它返回一个承诺,当所有其他承诺完成后(无论其最终状态如何),该承诺就会得到解决。这个超级承诺的解决结果是一个数组PromiseInspection
您可以查询的对象isFulfilled()
or isRejected()
并可以获得.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);
});
}));
}
并且,您可以像上面一样使用它:
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
});