16

所以最近生成器在 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

注意到错误了吗?然而,有一个参考错误——catch 会吞下它。

当我在 95% 的情况下使用 try/catch 时,我想要捕捉的是逻辑错误和 I/O 错误,而不是语法或类型错误。我想非常非常清楚这些。回调使用err第一个参数,在生成器中我不确定替代品是什么。

如何处理 JavaScript 生成器代码中的异常处理?

一个好的解决方案可以让我保留堆栈跟踪。

4

2 回答 2

10

所以基本上这与异步系统无关,而是与特定的错误处理有关。尝试这样的事情:

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
}
于 2013-11-08T12:49:32.040 回答
3

根据关于 generators 的最新ES6 草案,你可以调用 generator 的 "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,但是像gennygen-run这样的库)应该为您处理这个问题,这样您使用的库就不需要是发电机感知。

于 2013-11-25T00:06:42.487 回答