Promise.all 和 Promise.race 有效地使所有承诺“得到处理”,这是一种记录在案的行为吗?
Posted
技术标签:
【中文标题】Promise.all 和 Promise.race 有效地使所有承诺“得到处理”,这是一种记录在案的行为吗?【英文标题】:Is it a documented behavior that Promise.all and Promise.race effectively make all promises "handled"? 【发布时间】:2021-01-26 18:27:17 【问题描述】:在下面,代码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);
如果我像这样更改注释行:
//await Promise.race([p1, p2]);
await Promise.race([p1]);
...然后unhandledRejection
确实会因为p2
而被解雇,正如预期的那样。 Promise.all()
观察到相同的行为。
因此,Promise.race
和 Promise.all
有效地阻止了 unhandledRejection
事件,因为承诺没有赢得比赛但仍然被拒绝。这是记录在案的行为吗?我似乎在规范中找不到任何提及。
【问题讨论】:
【参考方案1】:是的,Promise.race
和 Promise.all
“处理”您传递给它们的所有承诺的结果,无论该结果是否与来自race
/all
的承诺的结算有关。因此,Promise.race
中的“失败”承诺仍然得到处理,尽管来自 Promise.race
的承诺只反映了获胜承诺所发生的事情。同样,如果 Promise.all
因为其输入承诺之一拒绝而拒绝,则稍后来自其他输入承诺的任何拒绝都会被处理,但不会对其进行任何处理。
您可以在规范中看到这一点,它将处理程序与传入的每个承诺的履行和拒绝都挂钩,例如在PerformPromiseRace 的步骤 3.i 中:
执行? Invoke(nextPromise, "then", « resultCapability.[[Resolve]], resultCapability.[[Reject]] »).
【讨论】:
不错!所以我可以在我的代码中依赖这种行为,我有一个用例:) 感谢您提供信息丰富的答案! 后续,so as it turns,unhandledRejection
如果在拒绝时没有附加任何处理程序,则将被触发。如果我们稍后附加处理程序并不重要。有趣的是,这就是它与 .NET Task
的不同之处,后者可以保持“休眠”状态,并且只有在垃圾收集时仍然未被观察到时才会触发 UnobservedTaskException
。以上是关于Promise.all 和 Promise.race 有效地使所有承诺“得到处理”,这是一种记录在案的行为吗?的主要内容,如果未能解决你的问题,请参考以下文章
JavaScript的Promise.all和Promise.race
(转载)理解和使用Promise.all和Promise.race