codeGig
codeGig

Reputation: 1064

better way of writing nodejs function of readfile/write file

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

Answers (3)

superjisan
superjisan

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

pkmiec
pkmiec

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

omarjmh
omarjmh

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

Related Questions