npm关于回调错误的指南

chh*_*vey 8 javascript error-handling asynchronous callback npm

我正在阅读npm的编码风格指南,并且遇到了以下非常神秘的建议:

要小心,永远不要扔任何东西.它比没用更糟糕.只需将错误消息作为第一个参数发送回回调.

它们究竟是什么意思,以及如何实现这种行为?他们建议自己调用回调函数吗?

这是我能想到的使用异步fs.readdir方法.

fs.readdir('./', function callback(err, files) {
  if (err) {
    // throw err  // npm says DO NOT do this!
    callback(err) // Wouldn’t this cause an infinite loop?
  }
  else {
    // normal stuff
  }
})
Run Code Online (Sandbox Code Playgroud)

小智 6

他们试图说的是你应该设计你的模块,这样异步函数不会抛出错误来捕获,而是在回调中处理(fs.readdir比如你提供的例子)......

所以,例如,这就是他们所说的你应该设计你的模块,如:

var example = {
    logString: function(data, callback){
      var err = null;
      if (typeof data === "string") {
        console.log(data);
      } else {
        err = {"message": "Data is not a string!"};
      }
      callback(err);
    }
}
Run Code Online (Sandbox Code Playgroud)

他们希望您设计它,以便最终用户可以处理回调内部的错误,而不是使用try/catch语句...例如,当我们使用example对象时:

example.logString(123, function(err){
  // Error is handled in callback instead of try/catch
  if (err) console.log(err)
});
Run Code Online (Sandbox Code Playgroud)

这会记录{"message": "Data is not a string!"},因为数据没有typeof等于"string".

以下是他们应该避免的一个例子:

当你有异步回调时,他们不希望你抛出错误...所以我们说我们重新设计了我们的模块,因此该logString方法抛出错误而不是将其传递给回调...就像这样:

var example = {
    logString: function(data, callback){
      if (typeof data === "string") {
        console.log(data);
      } else {
        // See, we're throwing it instead...
        throw {"message": "Data is not a string!"};
      }
      callback();
    }
}
Run Code Online (Sandbox Code Playgroud)

有了这个,我们必须完成整个try/catch语句,否则你将得到一个未被捕获的错误:

try {
  example.logString(321, function(){
    console.log("Done!")
  });
} catch (e) {
  console.log(e)
}
Run Code Online (Sandbox Code Playgroud)

最后的想法/总结:

我认为NPM建议这种方法的原因是因为它在异步方法中更易于管理.

NodeJS和JavaScript一般都喜欢拥有一个异步环境,以便将它们整合到一个地方,错误处理等等.

使用try/catch,它只需要一个额外的步骤,当它可以在回调内容易处理时(如果你是异步设计它,你应该这样做).