所以最近生成器在NodeJS中启动,我可以做类似的事情:
Promise.coroutine(function *(query){
var handle = yield db.connect(Settings.connectionString); //async, returns promise
var result = yield db.query(query); // async, returns promise
return result;
});
现在生成器非常棒,因为它们让我在JS中执行async / await。我真的很想能够做到这一点。
然而,出现了一个问题。生成器使用try / catch块,所以假设我的代码如下所示:
Promise.coroutine(function *(){
try{
var db = yield DBEngine.open("northwind"); // returns promise
var result = yield db.query("SELECT name FROM users"); // returns promise
return res;
} catch (e){
//code to handle exception in DB query
}
});
(注意,Promise.coroutine来自bluebird)
注意错误?但是有一个参考错误 - 捕获会吞下它。
当我在95%的情况下放置try / catch时,我想要捕获的是逻辑错误和I / O错误,而不是语法或类型错误。我想要非常清楚这些。回调使用err
第一个参数,而在生成器中,我不确定替换是什么。
一个好的解决方案可以让我保持堆栈跟踪。
答案 0 :(得分:9)
所以基本上这与异步系统无关,而是与特定的错误处理有关。尝试这样的事情:
var global_error_check = function(e) {
if (e && e.name === "ReferenceError") {
throw e;
}
// put other error types here that you don't want to catch
}
try {
...
} catch(e) {
global_error_check(e);
// handle other errors here
}
答案 1 :(得分:3)
根据最近的ES6 draft on generators,您可以调用生成器的“throw”函数来恢复生成器,但会抛出错误。
例如:
function procrastinatingAdd(x, y) {
var errMsg = "Expected number and got ";
setTimeout(function() {
if (isNaN(x)) gen.throw(new TypeError(errMsg + typeof x));
if (isNaN(y)) gen.throw(new TypeError(errMsg + typeof y));
gen.next(x + y);
}, 500);
}
var gen = function* () {
try {
var result = yield procrastinatingAdd(1, "foo");
log(result);
}
catch (e) {
log(e);
}
};
gen = gen();
gen.next();
大概是你用来管理你的生成器中的流控制的库(我没有看过Promises,但像genny和gen-run这样的库)应该为你处理这个库,这样你的库“消费不需要发电机感知。”