的承诺.all - resolve回调会被触发,尽管Promise被拒绝

Promise.all – resolve callback fires although a Promise is rejected

本文关键字:尽管 拒绝 Promise all 承诺 resolve 回调      更新时间:2023-09-26

在摆弄Promises以理解它们是如何工作的时候,我注意到一些我无法解释的东西。

给定这个例子:

var A = function () {
    return Promise.resolve();
};
var B = function () {
    return Promise.reject();
};
var c = A();
var d = B();
c.then(
  function () { console.log('A success'); },
  function () { console.log('A fail'); }
);
d.then(
  function () { console.log('B success'); },
  function () { console.log('B fail'); }
);
Promise.all([c, d]).then(
  function () { console.log('all success'); },
  function () { console.log('all fail'); }
);

首先触发单个resolve/reject回调,然后是拒绝Promise.all的回调。这是预期的,因为B拒绝了承诺。

但是当像这样写时,Promise.all的resolve回调触发:

var A = function () {
    return Promise.resolve();
};
var B = function () {
    return Promise.reject();
};
var c = A().then(
  function () { console.log('A success'); },
  function () { console.log('A fail'); }
);
var d = B().then(
  function () { console.log('B success'); },
  function () { console.log('B fail'); }
);
Promise.all([c, d]).then(
  function () { console.log('all success'); },
  function () { console.log('all fail'); }
);

这是意外的,因为两个Promise中的一个被拒绝了,所以all返回的Promise也应该被拒绝。

这里发生了什么-它与返回值有关吗?我需要在某个地方返回一个新的承诺吗?

你的两个例子看起来很相似,但并不完全相同。以下是then的文档(重点是我的):

调用onFulfilledonRejected,使用承诺的履行值或拒绝原因(酌情),并返回一个新的承诺,解析为所调用处理程序的返回值。

在你的第一个例子中,d被设置为B()的结果,这是一个被拒绝的承诺。一个新的承诺意味着记录了一些东西,但d没有改变。

在第二个示例中,d被更改为B().then(...)的结果,这是一个已解决的承诺。

您可能希望在拒绝处理程序中设置throw

你正在抑制第二种情况下的错误:

// d is promise which suppressed error from B()
var d = B().then(
  function () { console.log('B success'); },
  function () { console.log('B fail'); }
);

如果你想让d也被拒绝,你应该重新抛出错误:

var d = B().then(
  function () { console.log('B success'); },
  function (e) { console.log('B fail'); throw e; }
);