Reputation: 1064
How can i write this code in a better way.
var fs = require('fs');
var file = '/test.txt';
fs.readFile(file, 'utf8', function (err, txt) {
if (err) return console.log(err);
txt = txt + '\nAppended something!';
fs.writeFile(myFile, txt, function (err) {
if(err) return console.log(err);
console.log('Appended text!');
});
});
Suppose i have multiple callback then how can we prevent this callback of callback and so on....
getData(function(a){
getMoreData(a, function(b){
getMoreData(b, function(c){
getMoreData(c, function(d){
getMoreData(d, function(e){
...
});
});
});
});
});
Upvotes: 1
Views: 647
Reputation: 2074
What you're describing is callback hell and there's a couple of smart ways to get around it. I don't claim to be the know it all but there's a whole website called callbackhell.com that you might want to check out.
But for the short answer, you can do these things 1. keep your code shallow, or name your functions
Instead of writing your fs.readFile with an anonymous function, name it and call it like so
fs.readFile(file, 'utf8', function readFileCb(err, txt) {
if (err) throw new Error(err);
txt = txt + '\nAppended something!';
fs.writeFile(myFile, txt, function (err) {
// no need to return a console.log, just throw Error should suffice
if(err) throw new Error(err);
console.log('Appended text!');
});
});
2. Modularize your code. Have named functions or libraries that do exactly one thing
function writeFile(file, txt, cb){
fs.writeFile(file, txt, cb)
}
function writeFileCb(err){
if(err) throw new Error(err);
console.log('Appended Text!');
}
fs.readFile(file, 'utf8', function readFileCb(err, txt) {
if (err) throw new Error(err);
txt = txt + '\nAppended something!';
writeFile(myFile, txt, writeFileCb);
});
3. Ensure that all errors are caught. You seem to be doing that well, so kudos!
You can also use Promises, libraries like Async waterfall, but callbacks are an essential parts of JavaScript and going through callback hell is just a matter of having good sense in writing your code.
Upvotes: 0
Reputation: 2694
I suggest async waterfall
Your first snippet would look like following:
var txt;
async.waterfall([
function(callback) {
fs.readFile(file, 'utf8', callback);
},
function(txt, callback) {
txt = txt + '\nAppended something!';
fs.writeFile(myFile, txt, callback);
},
function(callback) {
console.log('Appended text!');
callback();
}
], function (err, result) {
console.log(err)
});
Upvotes: 2
Reputation: 13896
I really like bluebird for this:
First you have to 'promisify' fs
. n the example below they directly promisify the readFile
method:
var readFile = Promise.promisify(require("fs").readFile);
readFile("myfile.js", "utf8").then(function(contents) {
return eval(contents);
}).then(function(result) {
console.log("The result of evaluating myfile.js", result);
}).catch(SyntaxError, function(e) {
console.log("File had syntax error", e);
//Catch any other error
}).catch(function(e) {
console.log("Error reading file", e);
});
or:
var fs = Promise.promisifyAll(require("fs"));
// note now you have to put 'async' after the methods like so:
fs.readFileAsync("myfile.js", "utf8").then(function(contents) {
console.log(contents);
}).catch(function(e) {
console.error(e.stack);
});
Upvotes: 6