使用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();
});
});
这是一个针对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() {
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;
}
};
}
$.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) {
p = wrapInPromise(p);
return p.then(function(val) {
return new PromiseInspection(true, val);
}, function(reason) {
return wrapInPromise(new PromiseInspection(false, reason));
});
})).then(function() {
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();
});
});
而且,这里有一个使用标准ES6 promises从头构建的
settle()
类型函数。它返回一个单一的promise,当所有其他promises完成时解决(不考虑它们的最终状态)。这个超级promise的解决结果是一个
PromiseInspection
对象数组,您可以查询
isFulfilled()
或
isRejected()
并可以获得
.value()
或
.reason()
。
Promise.isPromise = function(p) {
return p && (typeof p === "object" || typeof p === "function") && typeof p.then === "function";
}
Promise.settle = function(promises) {
function PromiseInspection(fulfilled, val) {
return {
isFulfilled: function() {
return fulfilled;
}, isRejected: function() {
return !fulfilled;
}, isPending: function() {
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) {
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();
});
});
$.when
不接受数组? - Bergi