简体   繁体   English

为什么我不能在数组中推送文件?

[英]Why i can't push files in array?

I have a function for recursively finding files.我有一个递归查找文件的函数。 if type D is specified, I want only folders to be added to the array.如果指定了类型 D,我只想将文件夹添加到数组中。 and if type F then only files.如果输入 F 则只有文件。 It works fine with file search.它适用于文件搜索。 but if type D then nothing can be added although it is possible to output to the console.但是如果输入 D 则不能添加任何内容,尽管可以输出到控制台。 Why can't I add to the array and how can I fix it为什么我不能添加到数组中,我该如何修复它

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);
});

When type is D , you're currently decrementing pending only inside the if (stat && stat.isDirectory()) block, but pending 's amount also depends on the number of files in the directory, due to let pending = list.length;typeD ,您当前仅在if (stat && stat.isDirectory())块内递减pending ,但pending的数量还取决于目录中的文件数,因为let pending = list.length; . .

One way to fix it would be to decrement pending inside the else regardless:解决它的一种方法是在else内递减pending ,无论如何:

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

Or, to be cleaner and avoid some of the callback hell, use async functions and await instead, and then you can use Promise.all instead of manually checking indicies (which is tedious and can be error-prone).或者,为了更干净并避免一些回调地狱,使用async函数并改为await ,然后您可以使用Promise.all而不是手动检查索引(这很乏味并且容易出错)。 This also makes the function return a Promise properly (when done isn't passed):这也使函数正确返回一个 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;
        }
    }
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM