首页 > 解决方案 > 当带有 async fs.readdir 的递归函数完成执行时如何得到通知?

问题描述

我如何知道具有异步 fs.readdir 的递归函数何时完成执行?这里完整执行意味着给定目录中的所有文件都被处理。

我尝试返回一个承诺,并使用 async/await 进行后处理。

var func = (dirName) => {
    fs.readdir(dirName, (err, files) => {
        files.forEach(file => {
            console.log('Total Size = ' + size);
            console.log('Size Processed = ' + fileSizeProcessed);
            console.log('Processing : ' + file);
            var currentDir = path.join(dirName, file).toString();
            if ((fs.statSync((currentDir)).isDirectory())) {
                func(currentDir);
            }
            else {
                //Process File
            }
        })
    });
}

标签: javascriptnode.js

解决方案


您可以将执行包装在一个 Promise 中,然后您可以等待递归调用被处理,如果您使用 for of,则在函数的上下文中停止执行。最后,一旦处理完所有文件,我们就会通过通知一切都结束来解决最终的承诺。

const fs = require('fs')
const path = require('path')

const walk = dirName => {
  return new Promise((resolve, reject) => {
    fs.readdir(dirName, async (err, files) => {
      if (err) {
        return reject(err)
      }
      for (const file of files) {
        console.log(`Processing : ${file}`)
        const currentDir = path.join(dirName, file)
        if ((fs.statSync((currentDir)).isDirectory())) {
          await walk(currentDir)
        } else {
          console.log(`File ${file} processed`)
        }
      }
      resolve(`Folder ${dirName} processed, work finished`)
    })
  })
}

walk('./walk').then(response => console.log(response))

例如,在以下目录结构中:

在此处输入图像描述

如果执行上面的代码,输出如下:

Processing : file1.txt
File file1.txt processed
Processing : file2.txt
File file2.txt processed
Processing : file3.txt
File file3.txt processed
Processing : walk-sub1
Processing : walk-sub1-1
Processing : walk-sub1-1-file1.txt
File walk-sub1-1-file1.txt processed
Processing : walk-sub1-file1.txt
File walk-sub1-file1.txt processed
Processing : walk-sub1-file2.txt
File walk-sub1-file2.txt processed
Processing : walk-sub2
Processing : walk-sub2-file1.txt
File walk-sub2-file1.txt processed
Folder ./walk processed, work finished

记得处理内部 promise 中的错误,我没有这样做是为了简化示例


推荐阅读