Reputation: 111
I would like to read multiple files asynchronously in NodeJS. It is good to read multiple files at the same time, when the order of reading doesn't matter.
However, I'm trying to write contents of these files together into one file. I can write a file just fine, but how do I make sure that all the files have been read before I write all the contents into that one file?
Upvotes: 1
Views: 2139
Reputation: 7853
Using 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');
}
});
EDIT:
Using promises:
'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);
});
(Untested, but general idea's here)
As pointed out by libik, fs-promise
, util.promisify
or bluebird
are alternatives to promisify fs.readFile
and fs.writeFile
.
Upvotes: 3
Reputation: 23029
User Promises by one of the following method
Then save all this promises into array and use Promise.all
Other way around can be iterating variable i.e. var filesRead = 0
. When file is read, increase this number filesRead++
. After this, always check, if you read all the files, if so, you can do the writing
if (filesRead === numberOfFilesToRead){
//write things
}
Upvotes: 1