【问题标题】:NodeJS fs API: Detect Asynchronous CompletionNodeJS fs API:检测异步完成
【发布时间】:2015-02-25 19:05:50
【问题描述】:

我有一个 NodeJS 应用程序,它使用 fs API 从目录树中读取文件。我正在使用fs-walk 模块来遍历树。对于遇到的每个子目录,都会再次执行相同的函数来处理它。 (我不认为这是递归;相反,相同的函数绑定到每次处理目录时都会触发的事件。)文件由不同的函数处理,该函数对它们进行处理。

我想在不使用同步或阻塞代码的情况下读取所有文件后执行任意代码。我找不到任何方法来跟踪目录中的文件数量(例如倒计时),也找不到 fs.stat 中的任何属性来指示整个操作已完成。

有没有人找到办法做到这一点?我在节点文档或堆栈溢出中找不到任何内容。

【问题讨论】:

标签: node.js asynchronous fs


【解决方案1】:

在仔细查看fs-walk 库之后,看起来walk() 方法的第三个参数实际上是final callback。在内部,他们使用async 库,特别是async.whilst() 和async.waterfall() 方法,它们将在一切完成后执行最终回调。

我认为库创建者的意图是在所有异步操作完成后执行最终回调。如果这不起作用,您可能需要 file an issue in Github 处理它:

根据代码,你应该可以做到:

var walk = require('fs-walk';

walk('/some/dir', someFileOrDirHandler, function(err) {
    // This should be a final callback, if the first argument is present, 
    // then there was an error
    if (err) {
        /* handle it */
        return;
    }

    // Getting here indicates success
});

【讨论】:

  • 是的,但由于我永远不知道最后读取的文件是哪个,因此我可能会过早地执行最终的回调函数。这是因为我正在异步遍历多个目录。
  • 啊,但是您可以将目录数组作为第一个参数传递给walk() 方法吗?这能解决你的问题吗?
  • 很遗憾没有,因为有 x 个嵌套目录。为什么 nodejs 的 fs API 没有为任何给定目录提供“子”计数是不幸的 :(
【解决方案2】:

作为性能上的妥协,我最终使用同步访问文件系统的递归函数来计算文件总数。使用总数,然后我异步访问所有文件,每次减少总数。一旦总数达到零,我就执行了一个函数来处理所有已完成的数据。

var countAllFiles = new Promise(function (resolve, reject) {
    var total = 0,
    count = function (path) {
        var contents = fs.readdirSync(path), file, name;
        for (file in contents) {
            if (!contents.hasOwnProperty(file)) continue;
            name = path + '/' + contents[file];
            if (fs.statSync(name).isDirectory())
                count(name);
            else
                ++total;
        }
    };
    count('/path/to/tree/');
    resolve(total);
}).then(function (total) {
    walk.dirs('/path/to/tree/', handlerFunction, errorHandler);
    // for every file, decrement total.  Then, if it's zero, execute the code that
    // depends on all the read/write operations being complete
});

【讨论】:

    猜你喜欢
    • 2020-05-13
    • 2016-07-16
    • 1970-01-01
    • 2014-03-27
    • 1970-01-01
    • 1970-01-01
    • 2016-07-07
    • 2016-05-31
    • 1970-01-01
    相关资源
    最近更新 更多