2015-05-17 42 views
13

ECMAScript-6 iterator.throw(err)方法通常被描述为注入异常,就好像它发生在生成器中的yield语句一样。问题是这个异常的堆栈跟踪不包含对yield语句的文件/行,甚至它所在的函数的任何引用。相反,堆栈跟踪似乎只在异常对象为时生成构造为,它不在发电机内部。ES6生成器:来自iterator.throw的错误堆栈跟踪(err)

现在的问题是:如何获得违规产出报表的位置,堆栈跟踪或其他?

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 
} 

虽然这个问题不是具体的诺言,他们可能更容易以图片的问题。就我而言,我正在使用带有生成器和承诺的任务系统。假设函数ajax()返回一个Promise,如果这个被拒绝,那么使用这个机制将该错误转换成yield语句的throw。

调试器中的堆栈跟踪非常无用,因为我无法找到获取发生该注入的yield语句的函数,文件或行号的方法。调用iterator.throw(err)被视为重新抛出,并且不会获得新的堆栈信息,因此它只显示ajax()函数内的一个位置,该位置可以从多个位置调用,并通过在outer()(如上例中)中抛出一个新错误,抛出线显示所有错误。它们都没有暗示正在执行哪个生成器函数来调试错误。

我使用的是Chrome v42。

+1

如果您使用的是蓝鸟,那么Promise.coroutine可以为您处理大量这些东西。 –

+1

如果您认为缺少某些东西,您应该为Chrome提交缺陷报告/缺少功能rport。没有其他人可以做。我预计在所有浏览器中可能会出现更多的ES6的错误。 http://dev.chromium.org/for-testers/bug-reporting-guidelines –

+3

JavaScript中的堆栈跟踪总是绑定到您创建的'Error'实例,并且将始终显示在创建它们的行中。所以你的堆栈跟踪将始终显示调用'Error'的那一行。 –

回答

0

迭代器和承诺不能很好地混合(但) - 你基本上承诺在循环之外失败。

你可以通过承诺的结果返回给发电机避开这一点,是这样的:

function* one_of_many_generators() { 
    // ... 
    var promiseResult = yield ajax(url); // <-- what I need in the stack trace 

    // Now we're back in the generator with the result of the promise 
    if(notHappyWithResult(promiseResult)) 
     throw new Error('Reason result is bad'); 
    // ... 
} 

async function outer() { 
    var iterator = one_of_many_generators(); 
    let prms = iterator.next(); // runs to the first yield 

    // Wait for the promise to finish 
    let result = await prms; 

    // Pass the result back to the generator 
    let whatever = iterator.next(result); 
} 

只有:这是什么样的asyncawait做呢(这些关键字是只是语法糖对于结果传回的承诺产生器),并且如果使用它们,则常规try-catch将起作用。

iterator.throw主要是一种停止迭代的方法,不会向其中注入异常 - 堆栈的顶部仍然是您创建Error的任何位置。

最后,Chrome即将推出async iterators - 这些功能非常强大,都是关于promise的迭代。