【问题标题】:Why i can't push files in array?为什么我不能在数组中推送文件?
【发布时间】:2023-04-06 04:39:01
【问题描述】:

我有一个递归查找文件的功能。 如果指定了类型 D,我只想将文件夹添加到数组中。如果类型 F 则只有文件。它适用于文件搜索。但是如果类型 D 则不能添加任何内容,尽管可以输出到控制台。 为什么我不能添加到数组中,我该如何修复它

const type = T or D

const walk = (dir, done) => {
    let results = [];
    return new Promise((resolve, reject) => {
        fs.readdir(dir, (err, list) => {
            if (err) return done(err);
            let pending = list.length;
            if (!pending) return done(null, results);
            list.forEach((file) => {
                file = path.join(dir, file);
                fs.stat(file, function (err, stat) {
                    if (stat && stat.isDirectory()) {
                        if (type && type === 'D') {
                            console.log(file)
                            results.push(file);
                        }
                        walk(file, (err, res) => {
                            results.push(...res);
                            if (!--pending) done(null, results);
                        });
                    } else {
                        if (type === 'F') {
                            results.push(file);
                            if (!--pending) done(null, results);
                        }
                    }
                });
            });
        });
    })
};

walk(baseDir, (err, results) => {
    if (err) throw err;
    console.log(results);
});

【问题讨论】:

  • 这是一个奇怪的实现。您正在返回一个承诺(您永远​​不会解决)并接受done() 回调。您还缺少几个地方的错误处理。

标签: javascript node.js recursion filesystems


【解决方案1】:

typeD 时,您当前仅在if (stat && stat.isDirectory()) 块内递减pending,但pending 的数量还取决于文件 中的数量目录,由于let pending = list.length;

解决此问题的一种方法是在else 内减少pending,无论如何:

} else {
    if (type === 'F') {
        results.push(file);
    }
    if (!--pending) done(null, results);
}

或者,为了更简洁并避免一些回调地狱,请改用async 函数和await,然后您可以使用Promise.all 而不是手动检查指标(这很乏味并且容易出错)。这也使函数正确返回 Promise(当 done 未通过时):

const walk = async (dir, done) => {
    try {
        const list = await readdir(dir);
        const resultsArr = await Promise.all(list.map(async (fileName) => {
            const filePath = path.join(dir, fileName);
            const stats = await stat(filePath);
            if (stats.isDirectory()) {
                if (type === 'D') {
                    return [filePath, ...await walk(filePath)];
                }
                return walk(filePath);
            } else if (!stats.isDirectory() && type === 'F') {
                return filePath;
            }
        }));
        const flatResults = resultsArr.flat().filter(Boolean);
        if (done) {
            done(null, flatResults);
        }
        return flatResults;
    } catch (err) {
        if (done) {
            done(err);
        } else {
            throw err;
        }
    }
};

【讨论】:

    猜你喜欢
    • 2017-12-28
    • 2013-01-26
    • 1970-01-01
    • 2023-02-06
    • 2021-12-15
    • 2019-02-12
    • 2021-11-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多