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