Javascript npm';s关于回调错误的指导原则

Javascript npm';s关于回调错误的指导原则,javascript,asynchronous,error-handling,callback,npm,Javascript,Asynchronous,Error Handling,Callback,Npm,我通读了一遍,发现了以下非常隐晦的建议: 要非常小心,永远不要扔东西。这比没用还糟糕。只需将错误消息作为第一个参数发送回回调 它们到底是什么意思?如何实现这种行为?他们是否建议在其内部调用回调函数 下面是我对使用异步方法的看法 是的,这将导致无限循环。然而,他们并不是在谈论这种类型的回调。相反,npm引用了用于与模块交互的回调 要扩展您的示例,请执行以下操作: module.exports = { getDirectoryFiles: function (directory, done)

我通读了一遍,发现了以下非常隐晦的建议:

要非常小心,永远不要扔东西。这比没用还糟糕。只需将错误消息作为第一个参数发送回回调

它们到底是什么意思?如何实现这种行为?他们是否建议在其内部调用回调函数

下面是我对使用异步方法的看法


是的,这将导致无限循环。然而,他们并不是在谈论这种类型的回调。相反,npm引用了用于与模块交互的回调

要扩展您的示例,请执行以下操作:

module.exports = {
    getDirectoryFiles: function (directory, done) {
        fs.readdir(directory, function callback(err, files) {
            if (err) {
                return done(err);
            } else {
                return done(null, files);
            }
        })
    }
}
var yourLibrary = require("yourLibrary");

yourLibrary.getDirectoryFiles("./", function (err, files) {
    if (err) {
        console.log(err);
        // do something
    } else {
        // continue
    }
}
您应该将
err
传递给上述作用域中的回调函数,而不是当前正在处理的函数(在上述情况下,
callback
)。命名这些函数的唯一原因是帮助调试

他们之所以说不要抛出err,是因为node使用error-first回调。如果库使用回调,每个人都希望库将其错误作为第一个参数传播到回调。例如:

module.exports = {
    getDirectoryFiles: function (directory, done) {
        fs.readdir(directory, function callback(err, files) {
            if (err) {
                return done(err);
            } else {
                return done(null, files);
            }
        })
    }
}
var yourLibrary = require("yourLibrary");

yourLibrary.getDirectoryFiles("./", function (err, files) {
    if (err) {
        console.log(err);
        // do something
    } else {
        // continue
    }
}

他们想说的是,您应该设计模块,使异步函数不会抛出错误来捕获,而是在回调内部处理(如您提供的
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);
    }
}
他们希望您将其设计为最终用户可以在回调内部处理错误,而不是使用try/catch语句。。。例如,当我们使用
示例
对象时:

example.logString(123, function(err){
  // Error is handled in callback instead of try/catch
  if (err) console.log(err)
});
这将记录
{“消息”:“数据不是字符串!”
,因为数据的
类型不等于
“字符串”

下面是一个他们说你应该避免的例子: 他们不希望您在异步回调可供使用时抛出错误。。。假设我们重新设计了模块,
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();
    }
}
这样,我们必须执行整个try/catch语句,否则您将得到一个未捕获的错误:

try {
  example.logString(321, function(){
    console.log("Done!")
  });
} catch (e) {
  console.log(e)
}
最后想法/总结: 我认为NPM建议使用这种方法的原因是,在异步方法中,它更易于管理

NodeJS和JavaScript通常喜欢有一个异步环境,它非常适合将所有内容压缩到一个地方,包括错误处理等


使用try/catch,您只需再多走一步,就可以在回调内部轻松处理它(如果您是异步设计的,您应该这样做)。

@chharvey我没有重新定义
fs.readdir
。我只是借用了你的代码块并将其包装在一个模块中
yourLibrary
可以是任何您想要的,例如,计算第n个斐波那契数的方法。导入模块后,您希望其他人能够使用
yourLibrary.functionName(param1,callback)
使用它。是的,我的错。我一加上评论就意识到了这一点。尽管对于
getDirectoryFiles
函数包含
fs.readdir
的原因仍然令人困惑。我不知道这堆东西的顺序是什么。