处理NodeJS错误事件?

时间:2014-01-14 21:29:34

标签: node.js error-handling event-handling

我有一个拥有许多不同实用程序方法的worker类,并且当执行中的任何地方出现问题时会发出error个消息。由于NodeJS魔术,error消息是特殊的,如果没有任何东西在听它们,它们会变成抛出的错误,所以我现在这样做:

var myWorkerFunction = function(input) {
  var w = myFactory();
  try {
    w.dothis();
    w.dothat(input);
    w.hokeypokey();
    return w.finalize();
  } catch(e) {
    return false;
  }
}

我不知道,是否有可能完全避免使用try / catch块? NodeJS的文档似乎表明最好避免不重新抛出一个被捕获的异常(我在这里没有做任何检查,看到它真的是我的工人的逻辑引发了异常,而不是来自Node的关键错误)。

所以我想做类似的事情:

var myWorkerFunction = function(input) {
  var w = myFactory();
  w.on('error', function() {
    // How to tell caller of myWorkerFunction() I failed, 
    //   and stop the rest of the myWorkerFunction function? (return false)
  });
  w.dothis();
  w.dothat(input);
  w.hokeypokey();
  return w.finalize();
}

但是如何在该事件监听器函数中触发myWorkerFunction的“返回”?我也可以myWorkerFunction发出“错误”消息,但这只是将can踢到下一层,并且不会停止执行工作脚本(即如果dothis()失败,请'继续前进并致电dothat(input))。对于像这样的情况有编程模式吗?

编辑:我能提出的一个解决方案是:

var myWorkerFunction = function(input) {
  var w = myFactory();
  var hasFailed = false;
  w.on('error', function() {
    hasFailed = true;
  });
  w.dothis();
  if (hasFailed) return fa;se
  w.dothat(input);
  if (hasFailed) return false;
  w.hokeypokey();
  if (hasFailed) return false;
  var out = w.finalize();
  if (hasFailed) return false;
  return out;
}

在每行代码之前不得不经常检查我们是否失败,这不是很优雅。

1 个答案:

答案 0 :(得分:0)

对此有几点想法。首先,您可能需要查看Caolan McMahon的正常async nodejs library,因为感觉您正在重新创建流控制,而使用'async.waterfall'可以很好地处理。

如果您觉得不适合您 - 按照您采用的模式,您可以选择在完成每个步骤时发布事件(请参阅下面示例中的“完成”事件)。这将允许您监听这些事件,表明没有发生错误,并且进入下一步是有意义的。让'finalize'采取可选错误,让您的工作人员区分正常完成和异常完成。这没有经过测试,但这里的内容可能是这样的:

var myWorkerFunction = function(input) {
  var w = myFactory();
  w.on('error', function(error) {
    // Handle error, log whatever - and finalize with an error?
    w.finalize(error);
  });
  w.on('doneWithThis', function() {
    w.dothat(input);
  });
  w.on('doneWithThat', function() {
    w.hokeypokey();
  });
  w.on('doneWithHokeypokey', function() {
    w.finalize();
  });

  w.dothis(); //starts the ball rolling.
}