Node.js: Using Callback Functions for Synchronous Programming

Node.js code is asynchronous in nature. This article shows how you can use callback function in Node.js for synchronous programming.

I have written an article with examples on synchronous and asynchronous programming in Node.js. Here’s the link: Node.js: Asynchronous & Synchronous Code Programming

In the callback method, you simply pass a function as a parameter in another function and execute that function inside it.

Here’s a simple example of callback function:


function myCallback(data) {
    console.log('My callback data: ' + data);
}

function printData(callback) {
    callback('Kathmandu, Nepal');
}

printData(myCallback); 
// output: 
// My callback data: Kathmandu, Nepal

In the above code,

myCallback function is passed as a parameter to printData function
– and then, the myCallback function is executed inside the printData function
– “Kathmandu, Nepal” is passed as a parameter to the myCallback function

Callback function example with SetTimeout

  • We use callback function in Node.js because we have the need to execute certain codes only after any of our Input/Output (I/O) operation code gets completed.
  • The I/O operation can be like file read/write, or database table read/write.
  • The I/O operation will take some time to complete.
  • So, in the example below, we will use the settimeout Javascript method for simplicity assuming it to be the I/O operation.

  • Open terminal

  • Go to your Node.js application directory
  • In my case it is:

cd ~/Documents/nodejs

mukesh:nodejs chapagain$ pwd
/Users/mukeshchapagain/Documents/nodejs
  • Create a file app.js and add the following code in it

app.js


function printOne() {
    console.log('One');
}

function printTwo() {
    console.log('Two');
}

function printThree() {
    console.log('Three');
}

console.log('Start');

setTimeout(printOne, 1000);
setTimeout(printThree, 3000);
setTimeout(printTwo, 2000);

console.log('End');

OR, writing the setTimeout function inside the functions:


function printOne() {
    setTimeout(function() {
        console.log('One');
    }, 1000);
}

function printTwo() {
    setTimeout(function() {
        console.log('Two');
    }, 2000);
}

function printThree() {
    setTimeout(function() {
        console.log('Three');
    }, 3000);
}

console.log('Start');

printOne();
printThree();
printTwo();

console.log('End');
  • Run the application

node app.js

Output:


mukesh:nodejs chapagain$ node app.js
Start
End
One
Two
Three

The above code can also be written with a single function instead of three different functions like below:


function printData(data) {
    console.log(data);
}

console.log('Start');

// setTimeout(yourFunctionReference, 2000, param1, param2, paramN); // 2000 miliseconds = 2 seconds
setTimeout(printData, 1000, 'One');
setTimeout(printData, 3000, 'Three');
setTimeout(printData, 2000, 'Two');

console.log('End');

OR, writing the setTimeout function inside the functions:


function printData(data, time) {
    setTimeout(function() {
        console.log(data);
    }, time);
}

console.log('Start');

printData('One', 1000);
printData('Three', 3000);
printData('Two', 2000);

console.log('End');
  • Run the application

node app.js

Output:


mukesh:nodejs chapagain$ node app.js
Start
End
One
Two
Three

There’s a delay/timeout of some seconds in the code to print One, Two and Three. So, the code to print “End” gets executed before the code to print One, Two and Three.

Using Callback Function

We can use Callback functions to print ‘Start’ and then print ‘One’, ‘Two’ and ‘Three’. And, finally, print ‘End’.

app.js


function printOne(callback) {
    setTimeout(function() {
        console.log('One');
        callback();
    }, 1000);
}

function printTwo(callback) {
    setTimeout(function() {
        console.log('Two');
        callback();
    }, 2000);   
}

function printThree(callback) {
    setTimeout(function() {
        console.log('Three');
        callback();
    }, 3000);
}

console.log('Start');

printOne(function() {
    printTwo(function() {
        printThree(function() {
            console.log('End');
        });
    });
});
  • Run the application

node app.js

Output:


mukesh:nodejs chapagain$ node app.js
Start
One
Two
Three
End

An alternative example, using a single function instead of three functions to print One, Two and Three.


function printData(data, time, callback) {
    setTimeout(function() {
        console.log(data);
        callback(time);
    }, time);   
}

console.log('Start');

printData('One', 1000, function(time) {
    console.log(time);
    printData('Two', 2000, function(time) {
        console.log(time);
        printData('Three', 3000, function(time) {
            console.log(time);
            console.log('End');
        });
    });
});

Output:


mukesh:nodejs chapagain$ node app.js
Start
One
1000
Two
2000
Three
3000
End

Using multiple callbacks creates a situation called Callback Hell. Use of Promise or Async/Await is always recommended instead of using Callbacks. This article only intends to demonstrate how callbacks are used.

Asynchronous File Read Example

Let’s look into an example of reading a file using Node.js.

  • Open terminal
  • Go to your Node.js application directory
  • In my case it is:

cd ~/Documents/nodejs
  • Create a file named myfile.txt and add some text content to it

echo "This is a sample test file." >> myfile.txt
  • Create a file app.js and add the following code in it

app.js


const fs = require('fs');

console.log('Start reading file.');

fs.readFile('myfile.txt', 'utf-8', function(err, content) {
    if (err) {
        console.log(err);       
        throw err;
    }
    
    console.log(content);       
});

console.log('End reading file.');
  • Run the application

node app.js
  • The output will be:

mukesh:nodejs chapagain$ node app.js
Start reading file.
End reading file.
This is a sample test file.

It took some time to read the file. So, the application did not wait for the file read completion and jumped into the next code, i.e. printing “End reading file.”. And, finally when the file read was complete, the content of the file was printed at last.

Sychronous File Read using Callback Function

We can also use the readFileSync function which is the synchronous counterpart of the readFile function. But, in this example, we will use callback function for the same.


const fs = require('fs');

console.log('Start reading file');

function read(fileName, callback) {
    fs.readFile(fileName, 'utf-8', function(err, data) {
        if (err) {
            // console.log(err);        
            throw err;
        }
        
        callback(data);
    });
}

function printData(data) {
    console.log(data);
    console.log('End reading file');
}

const fileName = 'myfile.txt';
read(fileName, printData); 

Output:


mukesh:nodejs chapagain$ node app.js
Start reading file.
This is a sample test file.
End reading file.

Hope this helps. Thanks.