在 Node.js 中递归查找文件路径

问题描述 投票:0回答:1
const fs = require('fs').promises;

async function readMe(folder) {
    let result = [];
    try {
        const content = await fs.readdir(folder, { withFileTypes: true });
        for (let item of content) {
            if (item.isDirectory()) {
                await readMe(`${folder}/${item.name}`);
            } else {
                if (item.name === "sales.json") {
                    result.push(`${folder}/${item.name}`);
                }
            }
        }
    } catch (err) {
        console.log(err);
    }
    return result;
}

async function main() {
    const results = await readMe("stores");
    console.log(results);
}

main();

我试图列出“stores”文件夹的目录和子目录中 sales.json 的路径。我很困惑为什么上面的代码没有给出预期的结果。 在 if 语句中更改为这一行时:

result.push(... await readMe(`${folder}/${item.name}`) )

使代码正常工作。 如果我在目录和子目录中遇到任何 sales.json 文件,我会在 else 语句中处理路径。那么为什么我还需要再次将其推入 if 语句中?

node.js recursion file-handling
1个回答
0
投票

避免混合关注点以提高代码的可重用性。编写一个简单的

ls
来递归生成所有路径 -

import { readdir } from "fs/promises"
import { basename, join } from "path"

async function* ls(path = ".") {
  yield path
  for (const dirent of await readdir(path, { withFileTypes: true }))
    if (dirent.isDirectory())
      yield* ls(join(path, dirent.name))
    else
      yield join(path, dirent.name)
}

find
-
 派生 
ls

async function* find(path = ".", query) {
  for await (const f of ls(path))
    if (query(f) === true)
      yield f
}

使用

find
Array.fromAsync
得出结果 -

Array.fromAsync(
  search(".", f => basename(f) == "sales.json")
)
.then(console.log, console.error)

发电机可以暂停和恢复。这意味着如果可以尽早确定答案,我们可以避免做不必要的工作。如果我们只想要 first

sales.json
文件 -

async function findSalesJson(path = ".") {
  for await (const f of search(path, f => basename(f) == "sales.json"))
    return f
  throw Error("sales.json not found")
}

findSalesJson(".")
  .then(path => console.log("found sales.json at", path))
  .catch(console.error)

有关使用异步生成器的更多说明和其他方法,请参阅此问答

© www.soinside.com 2019 - 2024. All rights reserved.