Promise.all 和 Promise.race 是否有效地“处理”了所有承诺,这是一种记录在案的行为吗?

nos*_*tio 7 javascript node.js promise async-await

在下面,代码unhandledRejection不会被触发p2,即使它也被拒绝,尽管晚于p1:

process.on('unhandledRejection', (reason, promise) => 
  console.log(`unhandledRejection: ${reason}`));

async function delay(ms) {
  await new Promise(r => setTimeout(r, ms));
}

const p1 = async function f1(){
  await delay(100);
  throw new Error("f1");
}();

const p2 = async function f2(){
  await delay(200);
  throw new Error("f2");
}();

try {
  await Promise.race([p1, p2]);
  //await Promise.race([p1]);
}
catch (e) {
  console.error(e.message);
}
Run Code Online (Sandbox Code Playgroud)

如果我像这样更改注释行:

  //await Promise.race([p1, p2]);
  await Promise.race([p1]);
Run Code Online (Sandbox Code Playgroud)

...然后unhandledRejection确实被解雇了p2,正如预期的那样。观察到相同的行为Promise.all()。

因此,Promise.race并Promise.all有效防止unhandledRejection事件不赢得比赛,但仍然被拒绝的承诺。这是记录在案的行为吗?我似乎在规范中找不到任何提及。

T.J*_*der 6

是的,Promise.race并且Promise.all“处理”您传递给它们的所有承诺的结果,无论该结果是否与来自race/的承诺的结算有关all。所以“失败”的承诺 inPromise.race仍然被处理,即使承诺 fromPromise.race只反映了获胜承诺发生的事情。类似地,如果Promise.all因为其输入承诺之一拒绝而拒绝,则稍后会处理来自其他输入承诺的任何拒绝,但不会对它们进行任何处理。

您可以在规范中看到这一点,它将处理程序与传入的每个承诺的履行和拒绝挂钩,例如在PerformPromiseRace 的步骤3.i 中:

履行 ?Invoke(nextPromise, "then", « resultCapability.[[Resolve]], resultCapability.[[Reject]] »)。

  • 好的!所以我可以在我的代码中依赖这种行为,我有一个用例:)感谢您提供信息丰富的答案! (2认同)