惯用节点错误处理

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了惯用节点错误处理相关的知识,希望对你有一定的参考价值。

所以我正在做一个nodejs教程,它要求我使用模块来过滤目录中的所有文件。我应该使用惯用的方法来处理错误。下面是我的modules.js和我的主程序.js,然而,该程序说

Your additional module file [module.js] does not appear to pass back an
error received from fs.readdir(). Use the following idiomatic Node.js
pattern inside your callback to fs.readdir():
if (err) return
callback(err)

但我确实使用if (err)return callback(err);处理了第一行的错误

有人可以指出我做错了什么或我没有遵循的最佳做法?谢谢

module.exports = function filterList(dirName, extName, callback) {

fs.readdir(dirName, function callback(err, list) {

    if (err)
        return callback(err);
    for (var i = 0; i < list.length; i++) {
        if (path.extname(list[i]) == '.' + extName) {
            callback(null, list[i]);
        }
    };
});
}

我的program.js如下

var myMod = require('./module');
function printOut(err, result) {
    if (err) {
        console.log(err);
    };
    console.log(result);
}

myMod(process.argv[2], process.argv[3], printOut);
答案

这里有两个名为callback的函数,它会导致意外行为。

您的主要导出函数采用参数名称callback。然后在里面定义另一个名为`callback'的函数:

function filterList(dirName, extName, callback){ // <-- callback as arg
    fs.readdir(dirName, function callback(err, list) { // <-- callback defined again
        if (err)
          return callback(err);  // <-- which function is this calling?
  /* etc. */
}

当你最终return callback(err)你正在调用错误的功能。你想调用第一个 - 传递给filterList()的那个,但第二个是在范围内。

您可以将匿名函数传递给fs.readdir,因为您永远不需要调用它:

 fs.readdir(dirName, function(err, list) {
    if (err)
      return callback(err);  // <-- now there's only one call back

现在很清楚你正在调用正确的回调,而且它更具惯用性。

另一答案

你通过命名函数与参数相同来遮蔽你的callback。试试这个:

module.exports = function filterList(dirName, extName, callback) {
  fs.readdir(dirName, function cb(err, list) {
    if (err) return callback(err);
    for (var i = 0; i < list.length; i++) {
      if (path.extname(list[i]) == '.' + extName) {
        callback(null, list[i]);
      }
    };
  });
}

请注意,将第二个参数重命名为qazxsw poi现在命名为qazxsw poi,您实际上不需要为其命名,但它确实有助于堆栈跟踪和日志记录。

另外一件事,你将在循环中调用fs.readdir。有办法摆脱它,以及避免在循环中使用它的方法。

以上是关于惯用节点错误处理的主要内容,如果未能解决你的问题,请参考以下文章

如何使用适用于 DynamoDb 的 AWS Rust 开发工具包编写惯用的 Rust 错误处理?

Clojure 中的惯用错误处理

惯用的 goroutine 终止和错误处理

在golang中处理逻辑错误与编程错误的惯用方法

通过引用遍历节点的惯用方式

如果成功,从没有结果的函数返回错误的惯用方法是啥?