检查节点中的错误参数

Checking error parameters in node

节点中的约定是将错误参数传递给异步操作:

async.someMagicalDust(function(callback) {
     // some asynchronous task

     // […]
     callback();

}, function(err) {
     // final callback

    if(err) throw err;    
    // […]

});

也许我太天真了,但我从来都不是 if(variable) 表示法的忠实拥护者 — 可能是从 C 继承而来的,原因是 have already been discussed many times in the past.

另一方面,我有时会遇到一个 null 参数和这个错误检查:

if(typeof err !== 'undefined' && err !== null)

有点太冗长了。

另一个解决方案是

if(err != null)

但我认为 non-strict check 可能很棘手,尽管我认为与 null 进行比较时它是正常的。

在节点中检查错误参数的最佳方法是什么?

对我来说,处理错误的最好方法是 "if (err == null)" 这是我使用非严格运算符的唯一情况,原因如下:

  • 正如您之前所说,唯一始终有效的过度解决方案非常冗长
  • 你也可以只检查 "null" 或 "undefined",但我这样做了一次,几个月后,我刚刚更新了我的依赖项并且......约定改变了,并且模块发送的是 null 而不是 undefined。

这主要是 "convention" 的问题,我有我的,你当然也有你的...只是要小心选择两种 "good" 方式中的一种。

使用if(err).

它被设计成以这种方式使用。节点式回调应该仅在实际错误的情况下将错误设置为非假值。您找不到任何将 err 设置为 ''0 来表示错误的合理示例。

就像 YlinaGreed 指出的那样,如果模块约定从 null 变为 undefined 再到 0 甚至 NaN,你仍然是安全的。我从来没有被这个打过,只用过 if(err).

另一方面,您可能想使用 coffescript,它会为您翻译

unless err? then...

进入

if (typeof err === "undefined" || err === null) {

模仿最常见的模式。

一些链接证实了 if(err) 方法:

约定似乎将错误对象作为第一个参数传递,null 没有错误,所以即使传递空对象,它仍然是错误。

如果您使用流行的 express 框架,您应该使用从中间件到 return 的 next 回调,它遵循 errback 约定。

我相信大多数人更喜欢 next()next(null) 更简洁,这意味着第一个参数将评估为 undefined 而不是 null,这是当然完全正常使用。

Node 的主要回调约定是传递一个以 err 作为第一个参数的函数。根据我的经验,检查错误是否为真总是安全的——实际上,如果在出现错误时你的错误为空,那么问题更多在于实现。我总是希望 err 为 null 时不会发生任何错误。由于对错误和成功使用了单独的函数,这可能会造成混淆,这更像是 JQuery.Ajax 和 promises 的风格。我倾向于发现双重回调有点太冗长而无法调用。

根据您的示例,您似乎正在使用非常出色的异步库。如果我想执行并行选项,这就是我的设置方式:

function doAThing(callback) {
   var err;

   // do stuff here, maybe fill the err var

   callback(err);
}

function doAsyncThings(callback) {
  var tasks = [function(done) { // stuff to do in async
     doAThing(function(err) {
       done(err);
     });
  }];

  async.parallel(tasks, function(err) { // single callback function
       callback(err); // I send the error back up
  });
}

请注意,我没有抛出错误,而是将其冒泡备份到请求链中。由于您基本上是在说 "crash the whole app".

,因此我实际上想抛出错误的情况很少

我发现它更简单并且减少了调用函数时必须使用的参数数量。当你在整个过程中使用这个约定时,你可以通过简单地将回调作为参数传递而不是创建一个新的匿名函数来简化,就像这样:

function doAThing(callback) {
   var err;

   // do stuff here, maybe fill the err var

   callback(err);
}

function doAsyncThings(callback) {
  var tasks = [function(done) { // stuff to do in async
     doAThing(done);
  }];

  async.parallel(tasks, callback); // the error is sent back to the original function
}

我发现通常您想在调用它们的函数中处理这些错误。因此在这种情况下,doAsyncThings 的调用者可以检查是否存在错误并根据自己的范围进行适当的处​​理(如果是 API,可能会向用户提供更好的信息)。