【发布时间】:2015-07-29 05:05:00
【问题描述】:
ES6 方法:iterator.throw(err) 通常被描述为注入异常,就好像它发生在生成器中的 yield 语句中一样。问题是此异常的堆栈跟踪不包含对 yield 语句的文件/行的任何引用,甚至不包含它所在的函数。相反,堆栈跟踪似乎仅在异常对象为 constructed,它不在generator内。
问题是:我如何才能在堆栈跟踪或其他方式中获取有问题的 yield 语句的位置?
function* one_of_many_generators() {
// ...
yield ajax(url); // <-- what I need in the stack trace
// ...
}
function outer() {
var iterator = one_of_many_generators();
iterator.next(); // runs to the first yield
// inject exception at the yield statement
iterator.throw(Error("error")); // <-- top of stack trace shows here
}
虽然此问题并非特定于 Promises,但它们可能更容易描述问题。就我而言,我使用的是带有生成器和承诺的任务系统。假设的函数ajax() 返回一个 Promise,如果它被拒绝,则使用此机制将错误转换为在 yield 语句处的 throw。
调试器中的堆栈跟踪毫无用处,因为我找不到方法来获取发生此注入的 yield statement 的函数、文件或行号。调用iterator.throw(err) 被视为重新抛出,并且不会获得新的堆栈信息,因此它只显示ajax() 函数内的一个位置,该位置可以从许多地方调用,并在outer() 中抛出一个新错误,如在上面的示例中,所有错误都显示相同的 throw 行。两者都没有提示正在执行什么 generator 函数以调试错误。
我正在使用 Chrome v42。
【问题讨论】:
-
如果你使用的是 bluebird,那么 Promise.coroutine 可以为你处理很多这样的事情。
-
如果您认为缺少某些内容,您应该为 Chrome 提交错误报告/缺少功能报告。其他任何人都无能为力。我希望在所有 ES6 的所有浏览器中都可能出现更多这样的错误。 dev.chromium.org/for-testers/bug-reporting-guidelines
-
JavaScript 中的堆栈跟踪始终绑定到您创建的
Error实例,并将始终显示在创建它们的行中。因此,您的堆栈跟踪将始终显示调用Error的行。 -
@BenjaminGruenbaum 虽然这是真的,但似乎给生成器的非平凡使用留下了真正的开发问题。当调用一个抛出的普通函数时,堆栈至少显示调用行。但是如果生成器等待失败的承诺,似乎没有办法找出“调用”代码堆栈。如果这不是实现错误,那么它似乎是一个设计问题。
-
嗯,像 Bluebird 这样的库手动缝合堆栈跟踪。
标签: javascript ajax ecmascript-6 generator yield