2015-05-17 40 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的迭代。