【问题标题】:Promises with recursive calls带有递归调用的 Promise
【发布时间】:2021-02-03 13:47:30
【问题描述】:

我很失望没有找到解决方案,用 promise 递归和异步搜索 smb 共享中的文件。我的代码可能是正确的方式(我希望),但是内部的 readFiles 调用,什么都不返回。有什么想法可以解决我的困难吗?

readFiles(tree, path).then(files => {
  // all files in dirs
}); 


const readFiles = async (tree: Tree, path: string): Promise<string[]> => {
   const promises:Promise<string>[] = [];
   const entries = await tree.readDirectory(path);

   entries.forEach(entry => {
      promises.push(function(entry) {
         return new Promise<any>((resolve, reject) => {

            const files:string[] = [];

            if (entry.type == "Directory") {
                readFiles(tree, path + "/" + entry.filename.substring(2)).then(items =>
                    items.forEach(item => files.push(item)));

            } else {
                if (entry.filename.toLowerCase().endsWith(".cmz"))
                    files.push(path + '/' + entry.filename.substring(2));
            }

            return resolve(files);
         });
      }(entry));
   });

   return Promise.all(promises);
}

【问题讨论】:

  • 在递归调用 readFiles 之前需要 return 否则,顶级调用不会产生任何内容。
  • VLAZ,你能更准确一点吗?我添加了一个返回但相同的声音
  • 您的 resolve(files) 在 readFiles 承诺在 then 回调中返回之前返回。为什么不尝试使用 async/await 来解决这个问题,而不是创建新的 Promise。您可以等待致电readFiles
  • 附带问题:substring(2) 从文件名中删除了什么?

标签: javascript typescript asynchronous promise


【解决方案1】:

一些问题:

  • 您正在同步调用resolve,因此new Promise 不会等待递归承诺首先解决。

  • 当您手头已经有一个承诺(来自递归调用的承诺)时,使用 new Promise 是一种反模式

  • 递归承诺将解析为文件名数组(如果上述内容已更正),promises 将因此解析为文件名嵌套数组的数组,您需要将其展平。因此,您应该在已解析的数组上调用 .flat()

  • 问题较少,但不要将.forEach.push() 结合使用,而是使用.map() 的强大功能,它会为您创建数组。

这里是更正的代码:

const readFiles = async (tree, path) => {
    const entries = await tree.readDirectory(path);
    const promises = entries.map(async entry => {
        let filename = path + '/' + entry.filename.slice(2);
        if (entry.type == "Directory") {
            return readFiles(tree, filename);
        }
        if (filename.toLowerCase().endsWith(".cmz")) {
            return filename;
        }
        return []; // This result will disappear by applying flat().
   });
   return (await Promise.all(promises)).flat();
}

【讨论】:

  • 不错的解决方案!
猜你喜欢
  • 2015-07-17
  • 1970-01-01
  • 2017-03-25
  • 2015-10-28
  • 1970-01-01
  • 2019-04-28
  • 2016-05-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多