node.js-使用异步FS递归推入数组

发布于 2025-02-10 19:41:47 字数 652 浏览 2 评论 0原文

我正在尝试使用fs readdir来创建一个将文件名称递归(包括子目录中的文件)的函数,使用默认属性dir作为起点。

当我尝试console.log它工作正常的名称时,我无法弄清楚如何创建一个带有所有名称的数组(我没有在子目录中获取文件) 。

  import { readdir } from 'fs/promises';

   const arr = [];
   const reader = async (dir = `./src`) => {
      try {
         const items = await readdir(dir, { withFileTypes: true });
         items.map(item => item.isDirectory() ? reader(`${dir}/${item.name}`) : arr.push(item.name));
      }
      catch (err) {
         console.log(err);
      }
   };

   reader().then(() => {
      console.log(arr)
   })

谢谢!

I am trying to use the fs readdir to create a function that push file names into an array, recursively (including files in sub directories), using default attribute dir as a starting point.

When I tried to console.log the names it worked fine, but I could not figure out how to create an array with all the names in it (I'm not getting the files in the sub directories).

  import { readdir } from 'fs/promises';

   const arr = [];
   const reader = async (dir = `./src`) => {
      try {
         const items = await readdir(dir, { withFileTypes: true });
         items.map(item => item.isDirectory() ? reader(`${dir}/${item.name}`) : arr.push(item.name));
      }
      catch (err) {
         console.log(err);
      }
   };

   reader().then(() => {
      console.log(arr)
   })

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

分分钟 2025-02-17 19:41:47

您不是等待呼叫reader(),并且也没有调用。然后在其上调用()

因此,执行只是继续,console.log(arr)用空数组执行执行,然后随后调用reader()实际上发生并推到数组。

固定版本:

const arr = [];
const reader = async (dir = `./src`) => {
    try {
        const items = await readdir(dir, { withFileTypes: true });
        for (const item of items) {
            (item.isDirectory()) {
                await reader(`${dir}/${item.name}`);
            } else {
                arr.push(item.name);
            }
        }
    } catch (err) {
        console.log(err);
    }
};

reader().then(() => {
    console.log(arr)
})

You're not awaiting the call to reader(), and you're also not calling .then() on it.

so execution just continues, console.log(arr) executes with an empty array, and then subsequent calls to reader() actually take place and push to the array.

Fixed version:

const arr = [];
const reader = async (dir = `./src`) => {
    try {
        const items = await readdir(dir, { withFileTypes: true });
        for (const item of items) {
            (item.isDirectory()) {
                await reader(`${dir}/${item.name}`);
            } else {
                arr.push(item.name);
            }
        }
    } catch (err) {
        console.log(err);
    }
};

reader().then(() => {
    console.log(arr)
})
究竟谁懂我的在乎 2025-02-17 19:41:47

您很接近,但一个提示是一个错误是使用.map而无需使用其结果。 .map正在构建一个承诺数组,每个诺言都需要某种处理来组装最终输出。

我建议使用发电机,而不是将结果迫使阵列。 侧面步骤是.map的需要

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

async function* ls(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)
}
for await (const f of ls("/foo"))
  console.log("file found:", f)
file1
file2
file3
...

该 代码> toarray 可以使用 -

async function toArray(iter) {
  const r = []
  for await (const v of iter)
    r.push(v)
  return r
}
console.log("all files", await toArray(ls("/foo)))
[ file1, file2, file3, ... ]

You're close but one hint there's a mistake is the use of .map without using its result. .map is constructing an array of promises, each of which need some sort of processing to assemble the final output.

I would recommend using a generator instead of forcing the results into an array. This side-steps the need for .map and allows the consumer to process the resulting files asynchronously as they arrive -

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

async function* ls(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)
}
for await (const f of ls("/foo"))
  console.log("file found:", f)
file1
file2
file3
...

If indeed the consumer wishes to convert the asynchronous stream of elements to a flat array, a generic toArray can be used -

async function toArray(iter) {
  const r = []
  for await (const v of iter)
    r.push(v)
  return r
}
console.log("all files", await toArray(ls("/foo)))
[ file1, file2, file3, ... ]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文