【问题标题】:I'm trying to loop through all files in directory & its subfolders, get each file's text content & return an array of text content我正在尝试遍历目录及其子文件夹中的所有文件,获取每个文件的文本内容并返回一组文本内容
【发布时间】:2021-04-18 19:23:20
【问题描述】:

我已经创建了一个function 来递归地遍历directory(也是它的子文件夹)并检索所有具有特定扩展名的文件。

现在我创建了另一个function,它将获取检索到的文件的array,访问其内容并返回另一个array,其中包含每个文件的文本内容。

这是function 获取和返回每个文件的文本内容的代码:

const readFileContent = files => {
  files.forEach(file => {
    return fs.readFile(file, 'utf8', (err, data) => {
      if (err) throw err;
      console.log(data); // print all the text for each file
      return [data];
    });
  });
};

const allFilesTextContent = readFileContent(allSpecFiles);

console.log(allFilesTextContent); // prints undefined

但是,当我将function 存储在另一个variable 中并打印它时,我得到undefined。如果我在循环内打印,我会得到每个文件的文本内容。我也尝试将push() 转换为新的array,如下所示:

const readFileContent = files => {
  let results = [];
  files.forEach(file => {
    fs.readFile(file, 'utf8', (err, data) => {
      if (err) throw err;
      console.log(data); // print all the text for each file
      results.push(data);
    });
  });
  return results;
};

const allFilesTextContent = readFileContent(allSpecFiles);
console.log(allFilesTextContent); // print an empty array - []

我做错了什么?

【问题讨论】:

  • 您无法在callback之外访问async function结果
  • 你能为我提供一个可行的解决方案吗@ShivamSood 我一直在尝试将我的代码包装在async/await 但没有运气

标签: javascript node.js arrays function loops


【解决方案1】:

您将forEachmap 混淆并使用async 函数。

连续分辨率

import {promises as fs} from "fs";

const readFileContent = async (files) => {
  return await Promise.map(files, async (file) => {
    return await fs.readFile(file, 'utf8');
  });
};

并发分辨率

import {promises as fs} from "fs";

const readFileContent = async (files) => {
  return await Promise.all(
    files.map( (file) => fs.readFile(file, 'utf8') )
  );
};

【讨论】:

  • 这条线import {promises as fs, constants} from "fs";require() 的等价物是什么?另外,如果从未使用过,为什么我们需要constants? @emi
  • 对不起constants。刚刚从自己的项目中复制。
  • requiere 的承诺版本 fs 将是 const fs = require("fs/promises");
  • 添加了一个替代答案,具有并行/并发分辨率。
  • 如果这回答了您的问题,请将答案标记为已接受,而不是投票。
【解决方案2】:

这可能会有所帮助,如果您遇到任何错误,请告诉我

const fs = require("fs").promises;

const readFileContent = async (files) => {
  try {
    let results = [];
    for (const file of files) {
      results = await fs.readFile(file, "utf8");
    }
    return results;
  } catch (error) {
    return error;
  }
};

readFileContent(allSpecFiles)
  .then((data) => console.log(data))
  .catch((error) => console.error(error));

这是async/await 版本,因为它更简洁易读,但基本思想是,无论您在async/await 中运行什么函数,您都会得到promise,您需要使用then/catch 或另一个@987654326 来解决它@

【讨论】:

  • 您应该使用results.push( ... ) 而不是results = ...,否则您只会保存最后一个result。这也可以使用Promise.map() 而不是for( ... of ...) 循环来解决。
  • 你说得对,我只是举了一个例子,肯定需要改进。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-05
  • 2021-08-05
  • 2017-04-06
  • 2018-12-20
相关资源
最近更新 更多