在Node.js中不使用readFileSync()连续读取多个文件

时间:2019-05-06 16:30:21

标签: javascript node.js synchronization fs

如果使用readFileSync方法,则可以通过以下代码完成目标:

// Array of the file names
const files = [
    'a.txt',
    'b.txt',
    'c.txt'
]

for (let i=0;i < files.length();i++) {
    let result = fs.readFileSync(files[i]);
    console.log(files[i] + "  " + result.length);
}

console.log('done');

那么,如果我不能使用readFileSync方法,如何获得相同的输出?

我正在使用节点v6.10.3,因此我没有util.promisify(),但是我确实有几乎完整的Promise支持。

1 个答案:

答案 0 :(得分:1)

util.promisify()fs.readFile()Promise.all()配合使用,您可以执行以下操作,该操作并行异步读取所有文件,并在所有操作完成后按顺序提供缓冲区。以下内容还包含util.promisify()的polyfill,用于低于v8.0.0且支持Promise和ECMAScript 6的节点版本:

const fs = require('fs')
// const util = require('util')

function promisify (fn) {
  return function () {
    return new Promise((resolve, reject) => {
      fn.call(this, ...arguments, (error, value) => {
        if (error) reject(error)
        else resolve(value)
      })
    })
  }
}

const files = [
  'a.txt',
  'b.txt',
  'c.txt'
]

// const readFile = util.promisify(fs.readFile)
const readFile = promisify(fs.readFile)

Promise.all(files.map(file => readFile(file))).then(
  results => results.forEach((result, index) => {
    console.log(files[index], result.length)
  })
)

仅用util.promisify()魔术来解释一下这里发生了什么,它就变成了这种节点风格的回调:

fs.readFile(file, (error, result) => {
  if (error) {
    // handle error
  } else {
    // handle result
  }
})

兑现这一承诺:

util.promisify(fs.readFile)(file).then(result => {
  // handle result
}, error => {
  // handle error
})

但是我们改为在变量util.promisify(fs.readFile)中保留对readFile返回的函数的引用,以便可以为每个file调用它。