我正在阅读npm’s coding style guidelines并且遇到了以下非常神秘的建议:
要小心,永远不要扔任何东西。它比没用更糟糕。只需将错误消息作为回调的第一个参数发回。
它们究竟是什么意思?如何实现这种行为?他们建议在自己内部调用回调函数吗?
这是我能想到的使用异步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
}
})
答案 0 :(得分: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);
}
}
他们希望您设计它,以便最终用户可以处理回调内部的错误,而不是使用try / catch语句...例如,当我们使用example
对象时:
example.logString(123, function(err){
// Error is handled in callback instead of try/catch
if (err) console.log(err)
});
这会记录{"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();
}
}
有了这个,我们必须完成整个try / catch语句,否则你会得到一个未被捕获的错误:
try {
example.logString(321, function(){
console.log("Done!")
});
} catch (e) {
console.log(e)
}
我认为NPM建议这种方法的原因是因为它在异步方法中更易于管理。
NodeJS和JavaScript一般都喜欢拥有一个异步环境,以便将它们整合到一个地方,错误处理等等。
使用try / catch,它只需要一个额外的步骤,当它可以在回调中轻松处理时(如果你是异步设计它,你应该这样做)。
答案 1 :(得分:2)
是的,这会导致无限循环。但是,他们并没有谈论这种类型的回调。相反,npm引用了用于与模块交互的回调。
扩展你的例子:
module.exports = {
getDirectoryFiles: function (directory, done) {
fs.readdir(directory, function callback(err, files) {
if (err) {
return done(err);
} else {
return done(null, files);
}
})
}
}
您应该将err
传递给上述范围内的回调,而不是传递给您当前正在处理的函数(在上述情况下为callback
)。命名这些函数的唯一原因是帮助调试。
他们不说throw err
的原因是因为节点使用了错误优先回调。每个人都希望你的库(如果它使用回调)将其错误作为第一个参数传播给回调。例如:
var yourLibrary = require("yourLibrary");
yourLibrary.getDirectoryFiles("./", function (err, files) {
if (err) {
console.log(err);
// do something
} else {
// continue
}
}