Javascript 我如何使用承诺来让代码正常工作?
在我的代码完成对文件夹层次结构的递归之后,我想使用Javascript 我如何使用承诺来让代码正常工作?,javascript,node.js,recursion,promise,Javascript,Node.js,Recursion,Promise,在我的代码完成对文件夹层次结构的递归之后,我想使用then(),如下所示 一切都很好,尤其是使用 const fileNames = await fs.promises.readdir(dir); 及 但是,递归部分我不知道如何正确地实现以便 getFolderInfo(start).then((all_data)=>{ console.log('Done recursing the directory'); }); 工作正常 完成文件 const fs = require
then()
,如下所示
一切都很好,尤其是使用
const fileNames = await fs.promises.readdir(dir);
及
但是,递归部分我不知道如何正确地实现以便
getFolderInfo(start).then((all_data)=>{
console.log('Done recursing the directory');
});
工作正常
完成文件
const fs = require('fs');
const path = require('path');
// Configure & Initialize
let start = '_t/';
let depth = 1;
let counter = 0;
let total_size = 0;
// Definition
async function recurseFolders(dir, callback) {
const fileNames = await fs.promises.readdir(dir);
const listings = await Promise.all(
fileNames.map(async (thing_name) => {
const thing_path = path.join(dir, thing_name);
const stat = await fs.promises.stat(thing_path);
return {name: thing_name, path: thing_path, size: stat.size, isFolder: stat.isDirectory()};
})
);
listings.forEach(iterate);
function iterate (listing) {
counter++;
total_size += listing.size;
listing.counter = counter;
listing.total_size = total_size;
callback(listing);
if (listing.isFolder) {
recurseFolders(listing.path, callback);
}
}
}
async function getFolderInfo (start) {
await recurseFolders(start, (data) => {
console.log(data);
});
}
getFolderInfo(start).then((all_data)=>{
console.log('Done recursing the directory');
});
如果不尝试将文件夹层次结构展平为列表,则可以简化此操作。我对您期望使用的
计数器
和总大小
做了一些假设。我还忽略了未使用的depth
参数
const fs = require('fs');
const path = require('path');
async function recurseFolders(folderPath) {
const fileNames = await fs.promises.readdir(folderPath);
const fileData = await Promise.all(
fileNames.map(async (fileName) => {
const filePath = path.join(folderPath, fileName);
const fileStat = await fs.promises.stat(filePath);
if (fileStat.isDirectory()) {
return recurseFolders(filePath);
}
return {
name: fileName,
path: filePath,
size: fileStat.size,
isFolder: false
};
})
);
const folder = {
name: path.basename(folderPath),
path: folderPath,
files: fileData,
isFolder: true,
count: fileData.length,
size: 0
};
return fileData.reduce((total, file) => {
total.size += file.size;
if (file.isFolder) {
total.count += file.count;
}
return total;
}, folder);
}
recurseFolders('some/path/to/folder').then((file) => {
console.log(file);
}).catch((err) => {
process.exitCode = 1;
console.error(err);
});
此实现将返回如下所示的数据结构:
{
"name": "demo",
"path": "example/path/demo",
"files": [
{
"name": "dir1",
"path": "example/path/demo/dir1",
"files": [
{
"name": "dir2",
"path": "example/path/demo/dir1/dir2",
"files": [
{
"name": "file3.txt",
"path": "example/path/demo/dir1/dir2/file3.txt",
"size": 7412,
"isFolder": false
}
],
"isFolder": true,
"count": 1,
"size": 7412
},
{
"name": "file2.txt",
"path": "example/path/demo/dir1/file2.txt",
"size": 8364,
"isFolder": false
}
],
"isFolder": true,
"count": 3,
"size": 15776
},
{
"name": "file1.txt",
"path": "example/path/demo/file1.txt",
"size": 6870,
"isFolder": false
}
],
"isFolder": true,
"count": 5,
"size": 22646
}
如果您将fs工作放在它自己的函数中,问题就会很好地解决。此函数在给定路径上运行
stat
,并为每个条目回答修改后的stat对象
async function getStats(path) {
const names = await fs.promises.readdir(path);
let promises = names.map(async name => {
const pathName = path.join(path, name)
const stat = await fs.promises.stat(pathName);
return { name: name, path: pathName, size: stat.size, isFolder: stat.isDirectory() };
})
return await Promise.all(promises)
}
现在,只需调用给定路径的getStats,对每个结果应用回调,然后在包含的目录上递归,或者什么都不做
async function recurseFolders(path, callback) {
const stats = await getStats(path)
let promises = stats.map(async stat => {
callback(stat)
return await stat.isFolder ? recurseFolders(stat.path, callback) : Promise.resolve()
})
return await Promise.all(promises)
}
就是这样。递归
递归文件夹
调用没有等待
;这是故意的吗?我在调用中添加了一个wait,并使函数iterate
异步,但它仍然没有所需的行为。这是节点代码有没有办法使它在stackoverflow上的浏览器中运行?观察到的行为是什么?顺便说一句,您现在没有填充所有\u数据。在控制台记录“完成目录递归”的地方,应该完成目录递归all_data
只是它开始工作时的一个占位符。
async function getStats(path) {
const names = await fs.promises.readdir(path);
let promises = names.map(async name => {
const pathName = path.join(path, name)
const stat = await fs.promises.stat(pathName);
return { name: name, path: pathName, size: stat.size, isFolder: stat.isDirectory() };
})
return await Promise.all(promises)
}
async function recurseFolders(path, callback) {
const stats = await getStats(path)
let promises = stats.map(async stat => {
callback(stat)
return await stat.isFolder ? recurseFolders(stat.path, callback) : Promise.resolve()
})
return await Promise.all(promises)
}