Promise.race 中被拒绝的承诺会怎样?

What happens to rejected promises inside Promise.race?

通常,当 JavaScript 中的 Promise 未经处理就拒绝时,我们会得到 unhandled promise rejection 错误。

但是 Promise.race 逻辑忽略的所有被拒绝的承诺会发生什么?他们为什么不抛出同样的错误?

考虑以下测试:

const normal = new Promise((resolve, reject) => {
    setTimeout(() => resolve(123), 100);
});

const err = new Promise((resolve, reject) => {
    setTimeout(() => reject('ops'), 500);
});

const test = Promise.race([normal, err]);

test.then(data => {
    console.log(data);
});

上面的测试只是输出 123,但我们的 err 承诺没有 unhandled promise rejection 错误。

我正在尝试了解所有那些被拒绝的承诺会发生什么,因此才有了这个问题。

我们最终可能会得到一堆松散的承诺,这些承诺在后台继续 运行,没有任何错误处理,也没有任何关于未处理的承诺拒绝的报告。这似乎有点危险。


举个例子。我试图为异步迭代实现 combine 逻辑(类似于 ),这需要使用 Promise.race,同时跟踪拒绝传递给它的任何参数,因为combine 函数需要拒绝下一个请求。

来自MDN

The Promise.race() method returns a promise that fulfills or rejects as soon as one of the promises in an iterable fulfills or rejects, with the value or reason from that promise.

您的代码已完成,因为更快的 promise 调用 resolve。交换它们并拒绝。

const promise1 = new Promise((resolve, reject) => {
  setTimeout(resolve, 500, 'one');
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(reject, 100, 'two');
});

Promise.race([promise1, promise2]).then((value) => {
  console.log(value);
}).catch((value) => {
  console.log('error ', value);
});

Normally, when a Promise in JavaScript rejects without handling, we get unhandled promise rejection error.

是的,当一个承诺被拒绝时会发生这种情况,而这个承诺从未被 .then() 调用以安装处理程序,即链的最终承诺。

(注意 .catch(onRejected) 内部委托给 .then(undefined, onRejected),因此承诺被标记为处理相同。)

But then what happens to all rejected promises ignored by Promise.race logic? Why don't they throw the same error?

Promise.race 确实对其参数中的所有承诺调用 .then(),将它们标记为已处理:

Promise.race = function(thenables) {
    return new Promise((resolve, reject) => {
        for (const thenable of thenables) {
            Promise.resolve(thenable).then(resolve, reject);
        }
    });
};

请注意,当外部承诺已经解决时,它不会重新抛出错误,它只是被忽略了。这是设计使然:当使用 Promise.race 时,您声明您只对第一个结果感兴趣,其他所有内容都可以丢弃。从未赢得竞赛的 promise 中导致未处理的 promise 拒绝使您的应用程序崩溃将是相当具有破坏性的。