这里有很多建议,建议您确保不要让任何被拒绝的承诺无法得到兑现。如果您不这样做,建议将告诫您,这些错误将永远不会被发现,并且会被完全吞噬。什么都不会打印到控制台上。
此建议似乎已过时。当未处理拒绝的承诺时,现代浏览器和现代版本的Node似乎会打印警告。输入以下代码:
async function thisIsGoingToFail() {
await Promise.reject();
console.log('this should not print, as the line above should error');
}
async function main() {
await thisIsGoingToFail();
}
main();
如果在Node中运行此命令,则会得到:
(node:20760) UnhandledPromiseRejectionWarning: undefined
(node:20760) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)
(node:20760) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
标准建议是,源代码的最后一行应改为如下所示,以避免误吞错误:
main().catch(err => { console.err(err) });
但是看起来并不需要那样。所以这是我的问题:
unhandledrejection
即可在未处理承诺时打印警告。)catch
功能,还是让实现显示警告同样有用?答案 0 :(得分:3)
大多数未实现的诺言未处理被拒绝的诺言时,大多数现代实现都会向控制台打印警告,
✓ Node.js 自版本6.6.0起(请参见changelog):
承诺:现在,在第一次滴答之后,未处理的拒绝会发出过程警告。 (Benjamin Gruenbaum)#8223
在将来的版本中,未处理的承诺拒绝将以非零退出代码终止Node.js进程。
✓ Firefox 确实显示警告,但是我找不到哪个是第一个执行此操作的版本。 MDN docs这样说:
我们采用以下策略:如果某个承诺在其垃圾回收时被拒绝,,如果该承诺位于承诺链的末尾(即thatPromise.then从未被调用) ),然后打印警告。
注意:此警告是在错误发生后的某个时间生成的,可能会提供有关错误位置的较少信息。它通常表明需要插入适当的错误处理程序。当使用适当的拒绝处理程序时,它将有效地替换此延迟的报告。
✓ Chrome 确实显示警告,但是我再也找不到说明哪个是第一个版本的文档。 Chrome> = 49更进一步,并支持unhandledrejection
event,可让您添加自定义事件处理程序来处理所有未处理的拒绝承诺。
✓ Safari 也显示警告,并且由于版本> = 11,因此也支持unhandledrejection
事件。
✗ Edge 似乎还不支持它。
因此,看起来大多数现代浏览器(Edge除外)的确会显示针对未处理的拒绝的警告,但是没有明确的文档来保证将显示警告或将其立即显示。对于支持unhandledrejection
事件的浏览器来说,这似乎是个好主意。
tldr; 在撰写本文时,似乎最佳实践似乎仍然是使用catch
来拒绝顶级的承诺处理程序(以避免Edge中的错误和Node中终止的进程) )。对于Chrome和Safari,利用unhandledrejected
事件可能会有用。