节点最佳实践:在构造函数中抛出异步错误

时间:2014-02-17 16:58:58

标签: javascript node.js mocha

我正在使用Node,我有一个“类”,它将目录作为参数。它尝试创建该目录,如果失败,则会抛出错误:

function Config(dir) {
  fs.mkdir(dir, function(err) {
    if(err) throw new Error('Error', err);
  }
}

我的问题是,这是一种经过批准的方式吗?如果我要使用回调,那么我的程序的其余部分将必须驻留在该回调中,这对我来说似乎很奇怪。

当我尝试使用mocha编写测试时,这个问题就出现了,因为在异步调用中抛出了异常,因此无法使用mocha:

it('should throw an error on a bad directory', function() {
  var fn = function() {
    var badConfig = new Config('/asdf');
  };
  assert.throws(fn, Error);
});

我已经调查了域名作为解决单元测试问题的方法,但这似乎并没有解决我的问题(或者我没有正确实现它们)。

var d = domain.create().on('error', function(err) { throw err; }
d.run(function() {
  function Config(dir) {
    fs.mkdir(dir, function(err) {
      if(err) throw err;
    }
  }
});

最终,我正在寻找一种最佳实践,允许我向应用程序指出发生了一些不好的事情,并允许我为该解决方案创建测试。

2 个答案:

答案 0 :(得分:2)

您有三种可能性:

  1. 使用同步通话。正如AsolBerg解释的那样,你的案例恰好适合一些fs函数具有同步等价的原因。没关系,因为在您的情况下,您的所有应用程序都依赖于要加载的一个Config实例。但有案例

  2. 使用回调作为构造函数参数。

  3. 如果构造函数回调听起来真的太奇怪了,请将初始化代码放入init()方法,该方法需要回调。这是个人偏好的问题,而是使用这种技术。

  4. 最后一个选项,您可以在init()方法中返回Future。 NodeJS中有几个未来的库,它们是回调参数的优雅替代品。但是你不能在构造函数中使用它......因为构造函数的返回是创建的对象。

答案 1 :(得分:0)

听起来在这种情况下你实际上可能想要进行同步调用(例如,你的应用程序的其余部分依赖于此调用在继续之前完成)。因此,尽管通常不是您想要构建节点应用程序的方式,但您可以使用同步版本mkdirSync()。

http://nodejs.org/api/fs.html#fs_fs_mkdirsync_path_mode

然后,如果调用失败,您可以捕获错误并将其返回并(可能)退出应用程序。