javascript - 如何等待 Javascript 中的递归 Promise

标签 javascript recursion promise async-await

我已经用 javascript 编写了一个递归 Promise,它似乎工作正常,但我想使用 setTimeout() 对其进行测试,以确保在继续执行之前我正在正确等待。这是我的代码的要点:

try{
  await renameFiles(); // <-- await here
  console.log("do other stuff");
}
catch(){
}

const renameFiles = (path) => {
  return new Promise(resolve => {
    console.log("Renaming files...");

    fs.readdirSync(path).forEach(file) => {
      // if file is a directory ...
      let newPath = path.join(path, file);
      resolve( renameFiles(newPath) ); // <- recursion here!
      // else rename file ...
    }
    resolve();
  })

我已经像这样用 setTimeout() 测试了它:

const renameFiles = () => {
  return new Promise(resolve => {
    setTimeout(() => {
    // all previous code goes here
    },2000)
  }
}

输出是:

"Renaming files..."
"Renaming files..."
// bunch of renaming files...
"do other stuff"
"Renaming files..."
"Renaming files..."

所以它看起来像是在等待一段时间,但随后它会在某个时刻继续执行。

我也怀疑我测试错了。知道问题出在哪里吗?

最佳答案

如前所述 - 多次解析调用没有意义。然而,这并不是代码中的唯一问题。当对第一个子目录的递归调用开始时,根调用得到解决。此代码将按层次顺序处理目录

rename.js

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

const inputPath = path.resolve(process.argv[2]);
const newName = 'bar.txt';

async function renameFiles(filePath) {
    for (const file of fs.readdirSync(filePath)) {
        const newPath = path.join(filePath, file);
        const descriptor = fs.lstatSync(newPath);
        if (descriptor.isDirectory()) {
            await renameFiles(newPath)
        } else if (descriptor.isFile()) {
            await renameFile(file);
        }
    }
}

async function renameFile(file) {
    console.log(`Renaming ${file} to ${newName}`)
    return new Promise(resolve => {
       setTimeout(() => {
           console.log(`Renamed ${file} to ${newName}`)
           resolve();
       }, 300)
    });
}

async function main() {
    console.log(`Renaming all files in ${inputPath} to ${newName}`);
    await renameFiles(inputPath);
    console.log('Finished');
}

main();

你可以这样运行它

node rename.js relativeFolderName

或者如果顺序无关紧要,那么您可以使用@Tiago Coelho 提到的mapPromise.all

const renameFiles = async path => {
    const renamePromises = fs.readdirSync(path).map(file => {
      if (isDirectory(file)) {
          const newPath = path.join(path, file);
          return renameFiles(newPath)
      } else {
          return renamefile(file);
      }  
    });
    await Promise.all(renamePromises);
}

关于javascript - 如何等待 Javascript 中的递归 Promise,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56281473/

相关文章:

javascript - 为满足的每个部分包裹 li 项目

recursion - 惰性序列在消耗堆栈的递归调用中不起作用

node.js - React-native ListView 数据源不更新

javascript - 在 jQuery 之后 promise 每个

javascript - 以编程方式进行演示

javascript - 在运行时创建对象

javascript - 如何给vscode添加全局变量?

python - Python 为对象引用打印 "[...]"是什么意思?

javascript - javascript中的程序递归

node.js - 即使我返回 404,我的 promise 的成功 block 也总是执行