我有一个递归查找文件的功能。 如果指定类型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);
});
答案 0 :(得分:0)
当type
为D
时,您当前仅在pending
块内递减if (stat && stat.isDirectory())
,但是pending
的数量也取决于数量由于let pending = list.length;
,目录中文件的数量。
解决此问题的一种方法是在pending
内减小else
,无论如何:
} 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;
}
}
};