【问题标题】:Idiomatic Node error handling惯用的节点错误处理
【发布时间】:2018-08-08 19:44:28
【问题描述】:

所以我正在做一个 nodejs 教程,它要求我使用模块来过滤目录中的所有文件。而且我应该使用惯用的方法来处理错误。下面是我的 modules.js 和我的 main program.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);

【问题讨论】:

    标签: node.js error-handling callback idioms


    【解决方案1】:

    这里有两个名为 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
    

    现在很明显,您正在调用正确的回调,而且更符合习惯。

    【讨论】:

      【解决方案2】:

      您通过将函数命名为与参数相同的名称来隐藏您的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]);
            }
          };
        });
      }
      

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

      另外,在循环中调用callback 时会遇到问题。有办法摆脱它,也有办法避免它陷入循环。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-02-28
        • 1970-01-01
        • 2016-08-30
        • 2017-04-10
        • 2017-09-06
        • 2022-12-10
        • 2018-07-26
        • 1970-01-01
        相关资源
        最近更新 更多