【问题标题】:Promise.all – resolve callback fires although a Promise is rejected [duplicate]Promise.all – 尽管 Promise 被拒绝,但仍会触发解决回调 [重复]
【发布时间】:2017-03-18 21:38:00
【问题描述】:

在玩弄 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'); }
);

首先触发单个解析/拒绝回调,然后触发Promise.all 的拒绝回调。这是意料之中的,因为B 拒绝了 Promise。

但是当写成这样时,Promise.all 的解析回调会触发:

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 也应该被拒绝。

这里发生了什么——是否与返回值有关?我需要在某个地方返回一个新的 Promise 吗?

【问题讨论】:

  • 完全预期的行为,因为您处理异常......不要处理您的期望,然后您的所有人都会抓住它们。或者在您的拒绝处理程序中返回拒绝。
  • 你不是在等待B,你是在等待Bthen返回的promise。
  • 在第一个调用中,您已经在第一个 then 调用中发现了错误,并且在处理了错误之后,promise 链会自行重置。

标签: javascript promise


【解决方案1】:

您的两个示例看起来相似,但并不完全相同。这是thendocumentation(重点是我的):

使用 promise 的履行值或拒绝原因调用 onFulfilledonRejected(视情况而定)并返回一个新的 promise 解析为被调用处理程序的返回值。

在您的第一个示例中,d 设置为B() 的结果,这是一个被拒绝的承诺。新的承诺意味着记录了某些内容,但 d 没有更改。

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

你可能想在你的拒绝处理程序中throw

【讨论】:

    【解决方案2】:

    您在第二种情况下抑制错误:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-15
      • 2019-04-17
      • 2017-07-29
      • 1970-01-01
      相关资源
      最近更新 更多