我目前正在阅读Kyle Simpson撰写的“YKDJS - Async& Performance”,特别是第3章 - 承诺。
作者说任何没有注册拒绝处理程序的Promise都会收到一个默认的:
let p = new Promise(function(resolve, reject) { resolve("Yay!"); });
p.then(
function(val) { /* Do whatever */ }
/* Default rejection handler
, function(e) { throw e; } */
);
本章后面他声称Promise
的设计方式存在以下问题:
在任何Promise
链中,链中最后一个Promise
的一个处理函数中发生的任何错误都只是“吞下”而不是被报告。
他建议改变Promise
的工作方式,以便任何没有拒绝处理程序的Promise
通过抛出全局错误来报告错误。然后,他提出了一个可以在Promise#defer()
上使用的理论Promise
函数来阻止此报告行为。
现在我的问题是:这两个如何结合在一起?确实,没有拒绝处理程序的任何Promise
都会收到一个默认值,它会将拒绝值作为全局错误抛出:
Promise.reject("Oops");
/* VM668:1 Uncaught (in promise) Oops */
所以Promise
似乎已经按照他提出的方式工作了。
我误会了什么吗?谢谢你的帮助。
答案 0 :(得分:4)
中的Uncaught Handling he mentions
一些Promise库添加了注册内容的方法 喜欢"全球未处理的拒绝"处理程序,将被调用 而不是全局抛出的错误。但他们的解决方案如何 将错误识别为" uncaught"是有一个任意长度的计时器, 说3秒,从拒绝的时候开始。如果承诺是 拒绝,但在计时器触发前没有注册错误处理程序, 然后它假设你不会注册一个处理程序,所以 它没有被捕获。"
在实践中,这对许多图书馆来说都很有用,就像大多数用法一样 模式通常要求Promise之间存在重大延迟 拒绝和观察拒绝。
已被标准化为unhandled rejection warnings(不使用任意计时器,但立即开火)。它确实很有效。
中说明[当]我们不是在听那种拒绝,[...]它会 默默地保持着未来的观察。如果你从来没有观察过它 在调用
then(..)
或catch(..)
时,它将无法处理。一些 浏览器开发者控制台可能会检测到这些未处理的拒绝和 报告他们,但这不能得到可靠的保证;你应该永远 遵守承诺拒绝。