问题描述
例如
p = new Promise(function (resolve, reject) {
throw 'err';
});
p.done();
在大多数 promise polyfill 库中,done 会抛出错误,当前执行会退出.
In most promise polyfill libs, the done will throw an error, and the current execution will exit.
但是如果我们使用p.then()
,什么都不会发生.错误被承诺吞没了.如果我们使用p.catch
,我们没有办法退出当前的执行.我想实现如下目标:
But if we use p.then()
, nothing will happen. The error is swallowed by the promise. If we use p.catch
, we have no way to exit current execution. I want to achieve something like:
try {
// something
} catch (err) {
if (check(err)) {
throw err;
}
}
推荐答案
No.
不仅 .done
可能不会在规范的未来版本中得到支持 - 它是不需要的.引用 Mariusz 链接的线程:
No.
Not only will .done
likely not be supported in the future versions of the spec - it is unneeded. Quoting from the threads Mariusz linked to:
多米尼克:
它仍然容易出错:如果你犯错,甚至一次不遵守规则,你可能会永远使错误消失.
Mark Miller(承诺概念的先驱):
Mark Miller (who pioneered the concept of promises):
请注意,弱引用(希望在 ES7 中)将为我们提供弥合这一差距所需的诊断工具之一.使用弱引用,如果在没有通知任何处理程序的情况下收集了一个被拒绝的承诺,我们可以安排这生成一个诊断.承诺实现必须将原因保留在承诺的执行程序(事后 gc 处理程序)中,以便在发现承诺已被拒绝后进行诊断报告.
Yehuda Kats 关于 RSVP 的错误处理程序:
Yehuda Kats on RSVP's error handler:
我们在 RSVP 中采用的方法是安装一个默认抛出的未处理的承诺监视器.
如果您知道将附加异步错误处理程序,您可以通过附加一个 noop 失败处理程序来选择一个特定的 Promise 退出此行为.我们可能会为此加糖 (.undone :p)
You can opt a particular promise out of this behavior by attaching a noop failure handler, if you know that you will be attaching asynchronous error handlers. We will probably have sugar for this (.undone :p)
根据我们的经验,将负担从字面上的每个人转移到可能想要附加异步错误处理程序的人是合适的.
In our experience, moving the burden from literally everyone to people who may want to attach async error handlers is appropriate.
而且,从规范之前的实际存储库中,Domenic 说:
And, from the actual repo that preceded the spec, Domenic said:
完成的工作将通过将未处理的拒绝跟踪功能集成到开发工具中来完成.据我所知,大多数 TC39ers 以及我自己都认为这足以使规范完整.
规范委员会不仅忽略了 .done
,他们认为这是不必要的并且容易出错.新的现代 Promise 库会自动检测未处理的拒绝 - 这方面的两个例子是 When promises 和 Bluebird promises 率先提出了这一想法.
The spec committee did not just ignore .done
, they deemed it was unnecessary and error prone. New modern promise libraries automatically detect unhandled rejections - two examples of this are When promises and Bluebird promises that pioneered the idea.
.done
是一个工件 - 源于浏览器无法检测到未处理的拒绝的事实.事实是 - 确定性地检测它们是不可能的,但在绝大多数情况下是完全可能的.
.done
is an artifact - originating from the fact the browser could not detect unhandled rejections. Truth is - detecting them deterministically is impossible but for the vast majority of cases it is completely possible.
不相信我?打开 Firefox 并使用它的原生承诺:
Don't believe me? Open Firefox and play with its native promises:
p = new Promise(function (resolve, reject) {
throw 'err';
});
// Logs as error: Unhandled error: `err`
简单地说 - firefox 使用垃圾收集钩子来确定 promise 是否处于未处理状态并触发全局错误处理程序,该处理程序默认为在屏幕上写入.
Simply put - firefox uses garbage collection hooks in order to determine promises were disposed in an unhandled state and fires a global error handler which defaults to writing on the screen.
现在,问题是原生 promise 还不是很可用——因为在 IE 中它们不存在,而且在 Chrome 中尚未实现未处理的拒绝检测——但它即将到来,它将在那里.同时,您可以使用像 Bluebird 这样的 ES6 兼容库,它会为您进行拒绝跟踪.
Now, the problem is native promises are not very usable yet - since in IE they don't exist and in Chrome unhandled rejection detection was not yet implemented - but it's coming and it'll be there. Meanwhile you can use an ES6 compatible library like Bluebird which will do this rejection tracking for you.
如果你想完成 polyfill(我强烈建议反对) - torazaburo 的 polyfill 有一些缺点.它在 Promise 原型上声明了一个可枚举属性,通常这不是规范的设计方式 - 您应该子类 Promise 以扩展它们而不是猴子修补它们 - 遗憾的是目前没有实现支持这一点.
If you want to polyfill done (which I strongly recommend against) - the polyfill by torazaburo has a few shortcomings. It declares an enumerable property on the promise prototype and generally this is not how the spec was designed - you are expected to subclass promises in order to extend them rather than monkey patch them - sadly no implementations currently support this.
简而言之:
- 在使用原生 promise 之前等待它们稳定下来 - 同时您可以使用实现规范的库,例如 Bluebird.当它稳定时,没有
.done
根本不是问题. - 利用模式检测错误 - 例如查看 处置器模式在这里.
- 在可用时使用开发者工具,长堆栈跟踪和异步调试是一大优点.另请注意,如果您想要有意义的堆栈跟踪,则不应抛出字符串.
- Wait for native promises to stabilize before you use them - in the meanwhile you can use libraries that implement the spec like Bluebird. When it stabilizes not having
.done
will not be an issue at all. - Utilize patterns for detecting errors - for example check out the disposer pattern here.
- Use the developer tools when available, long stack traces and and async debugging are big plusses. Also note you should not throw strings if you want meaningful stack traces.
祝你好运,编码愉快.
这篇关于Javascript ES6 会承诺支持'done' api吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!