NodeJS - 如何异步读取多个文件并将读取的内容写入一个文件

NodeJS - How to read multiple files asynchronously and write read contents to one file

我想在 NodeJS 中异步读取多个文件。当读取顺序无关紧要时,同时读取多个文件是很好的。

但是,我正在尝试将这些文件的内容一起写入一个文件中。我可以很好地写入一个文件,但是在将所有内容写入该文件之前,如何确保所有文件都已被读取?

用户通过以下方法之一承诺

  1. 创建承诺,每个承诺在读取文件时解决
  2. 使用 bluebird 为 fs 创建类似 Promise 的方法
  3. 使用fs-promise模块

然后将所有这些承诺保存到数组中并使用 Promise.all

其他方法可以迭代变量,即 var filesRead = 0。读取文件时,增加此数字 filesRead++。在此之后,经常检查,如果你读取了所有文件,如果是,你可以写

if (filesRead === numberOfFilesToRead){
    //write things
}

使用async

'use strict';

let fs = require('fs'),
    async = require('async'),
    inputs = ['in1', 'in2'],
    output = 'out';

function fuse(inputs, output, callback) {
    async.map(inputs, (path, callback) => {
        fs.readFile(path, callback);
    }, (err, contents) => {
        if(error) {
            callback(error);
        } else {
            fs.writeFile(output, contents.reduce((a, b) => {
                return a + b;
            }), callback);
        }
    });
}

fuse(inputs, output, (error) => {
    if(error) {
        console.log('Error: ' + error);
    } else {
        console.log('OK');
    }
});

编辑:

使用承诺:

'use strict';

const fs = require('fs'),
    inputs = ['in1', 'in2'],
    output = 'out'

// Promisify fs.readFile
function read(file) {
    return new Promise((resolve, reject) => {
        fs.readFile(file, (error, data) => {
            if(error) {
                reject(error);
            } else {
                resolve(data);
            }
        });
    });
}

// Promisify fs.writeFile
function write(file, data) {
    return new Promise((resolve, reject) => {
        fs.writeFile(file, data, (error) => {
            if(error) {
                reject(error);
            } else {
                resolve();
            }
        });
    });
}

Promise.all(inputs.map(read)) // Read all files
    .then((data) => { // data will be a array of the data in the files
        const outData = data.reduce((a, b) => {
            return a + b; // concatenate the data
        })
        return write(output, outData); // write the output
    })
    .then(() => {
        console.log('OK');
    })
    .catch((error) => {
        console.error(error);
    });

(未经测试,但大致思路在这里) 正如 libik 所指出的,fs-promiseutil.promisifybluebird 是 promisify fs.readFilefs.writeFile.

的替代方案