在 .map() 中使用 fse.readFile()

Use fse.readFile() inside .map()

我正在尝试使用 promises 读取 Node.js 中多个文件的内容。由于标准 fs 模块没有提供足够的 promise 接口,我决定使用 fs-extra 代替,它提供与默认 fs 模块几乎相同的功能,但有一个额外的 promise 接口。

按如下所示读取单个文件的内容,并将文件的内容记录到控制台:

const fse = require('fs-extra')

const filePath = './foo.txt'


fse.readFile(filePath, 'utf8')
    .then(filecontents => {
        return filecontents
    })
    .then(filecontents => {
        console.log(filecontents)
    })

但是,我需要处理给定目录中的多个文件。为此,我需要执行以下步骤:

  1. 使用 fse.readdir() 获取目录内所有文件的数组 - 完成
  2. 使用 path.join.map() 加入文件名和目录名以获得一种基本文件路径,以避免遍历数组 - done
  3. 使用 fse.readFile() 在另一个 .map()
  4. 中读取文件内容

这三个步骤具体实现如下:

const fse = require('fs-extra');
const path = require('path');

const mailDirectory = './mails'


fse.readdir(mailDirectory)
    .then(filenames => {
        return filenames.map(filename => path.join(mailDirectory, filename))
    })
    .then(filepaths => {
        // console.log(filepaths)
        return filepaths
            .map(filepath => fse.readFile(filepath).then(filecontents => {
                return filecontents
            }))
    })
    .then(mailcontents => {
        console.log(mailcontents)
    })

如上所述,第 1 步和第 2 步运行良好。但是,我无法在最后一个 .map() 中使用 fse.readFile() 读取文件内容,这导致

[ Promise { <pending> },
  Promise { <pending> },
  Promise { <pending> },
  Promise { <pending> },
  Promise { <pending> } ]

表明承诺尚未解决的输出。我假设这个未解决的承诺是 fse.readFile() 函数返回的承诺。但是我无法正确解决它,因为我的第一个片段中的类似方法非常有效。

我该如何解决这个问题?它到底来自哪里,因为我是 JS 领域的新手,尤其是 Node.js 领域的新手?

你有一系列的承诺。您应该使用 Promise.all():

等待他们
const fse = require('fs-extra');
const path = require('path');

const mailDirectory = './mails'


fse.readdir(mailDirectory)
    .then(filenames => {
        return filenames.map(filename => path.join(mailDirectory, filename))
    })
    .then(filepaths => {
        // console.log(filepaths)
        return filepaths
            .map(filepath => fse.readFile(filepath).then(filecontents => {
                return filecontents
            }))
    })
    // Promise.all consumes an array of promises, and returns a 
    // new promise that will resolve to an array of concrete "answers"
    .then(mailcontents => Promise.all(mailcontents))
    .then(realcontents => {
        console.log(realcontents)
    });

此外,如果您不想对 fs-extra 有额外的依赖,您可以使用节点 8 的新 util.promisify()fs 遵循面向 Promise API.