I recently ran into problem while executing a node.js file. I will post the code and explain what the problem is.
I have 2 files namely testit.js and test.js
In test.js, I am passing an array object, containing the file paths of textfiles, to the testit.js using module.exports
["a.txt","b.txt"]
In testit.js, module.exports.text accepts an array object of filenames,
processes each of it through Object.keys(texts).forEach
,
reads each of the returned buffer values through readFile
,
returns the text containing in that buffer through takeAction
and stores it in an array object newtexts
.
But when the newtexts is resolved and call returns to then(), in which newtexts is being printed on commandline, it returns an EMPTY ARRAY OBJECT rather than returning an array object of file contents of each those files.
Can someone explain me where I went wrong in the code? Thanks a ton in advance.
test.js
var testit = require('./testit');
var texts = ["a.txt","b.txt"];
testit.text(texts).then(function(newtexts){
console.log(newtexts);
});
testit.js
var Promise = require('bluebird');
var S = require('string');
var fs = require("fs");
module.exports.text = function(text){
var texts = text;
var length = Object.keys(texts).length;
return new Promise(function(resolve, reject){
var newtexts = [];
var takeAction = function(text) {
return text.toString();
}
var readFile = function (filename, enc){
return new Promise(function (resolve, reject){
fs.readFile(filename, enc, function (err, buffer){
if(err)
reject(err);
else
resolve(buffer);
});
});
}
Object.keys(texts).forEach(function(key){
readFile(texts[key]).then(function(text){
newtexts[key] = takeAction(text);
});
});
resolve(newtexts);
});
}
You need to actually wait for all the readFile Promises to resolve before you resolve the overall Promise.
Replace
Object.keys(texts).forEach(function(key){
readFile(texts[key]).then(function(text){
newtexts[key] = takeAction(text);
});
});
resolve(newtexts);
With something like this:
var textPromises = texts.map( function (fileName) {
return readFile(fileName).then( function (text) {
newtexts[fileName] = takeAction(text);
});
});
Promise.all(textPromises).then( function () {
resolve(newtexts);
});
The basic idea here is to store the Promise returned by each call of readFile into an array (or more accurately, we store a Promise that resolves after readFile is finished and after the result is processed and stored into newtexts), and only when all of the Promises in the array have resolved do we resolve the promise we return from this function.