如何等待Java中的递归承诺 [英] How await a recursive Promise in Javascript

查看:54
本文介绍了如何等待Java中的递归承诺的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have written a recursive Promise in javascript which seems to be working fine but I wanted to test it using setTimeout() to be sure that I'm awaiting correctly before continuing with the execution. Here is the gist of my code:

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()对其进行了测试,如下所示:

I've tested it with setTimeout() like this:

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..."

因此,它似乎正在等待一会儿,但随后它会在某个时刻继续执行.

So it looks like it's awaiting for a bit but then it continues the execution at some point.

我也怀疑我测试错了.知道问题可能在哪里吗?

I'm also doubting I'm testing it wrong. Any idea where the problem may be?

推荐答案

-多次解析调用没有意义.但是,这不是代码中的唯一问题.在第一个子目录的递归调用开始时,根调用已解决.该代码将按层次结构顺序处理目录

As already mentioned - multiple resolve invocations don't make sense. However that is not the only problem in the code. Root invocation got resolved when its recursive call started for first sub directory. This code will process directories in hierarchical order

rename.js

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提到的 map Promise.all

or if order doesn't matter, then you can use map and Promise.all as mentioned by @Tiago Coelho

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

这篇关于如何等待Java中的递归承诺的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆