Hello Sunil
Javascript callback-functions feature image

How To Easily Understand Callbacks In JavaScript

Understanding callbacks in JavaScript is one of the very first things that anyone starting to program with JavaScript should know. It’s also one of the more difficult concepts for newcomers to understand.

In this post, I will show you how I came to fully understand exactly what they are and how to use them.

Before getting started, I assume that you understand how functions work in JavaScript. If not, check out the JavaScript functions guide to learn more.

So let’s start…

JavaScript Callback Function

Let us understand term Callback by an real-world example:

Suppose, you are calling to your Girlfriend (If you have) and she is busy in another call then she send message to you : “I am busy right now, Call back you later.!!”.

After completing her work, she calls you back and this is what call back in JavaScript as well.

In JavaScript, when a function is executing (Girlfriend is talking with someone) then after function execution is completed another function is started for execution this is callback function.

So what exactly are callback functions?

As we know JavaScript function is a block of code that performs a certain task when called.

For example,

// function
function greet(name) {
    console.log('Hi' + ' ' + name);
}

greet('Sunil'); // Hi Sunil

In the above program, a string value is passed as an argument to the greet() function.

In JavaScript, you can also pass a function as an argument to a function. This function that is passed as an argument inside of another function is called a callback function.

In simple terms, a callback function is just a function you can pass to another function for it to be invoked after performing another action.

For example,

// function
function greet(name, callback) {
    console.log('Hi' + ' ' + name);
    callback();
}

// callback function
function callMe() {
    console.log('I am callback function');
}

// passing function as an argument
greet('Sunil', callMe);

//Hi Sunil
//I am callback function

In the above program, there are two functions.

While calling the greet() function, two arguments (a string value and a function) are passed. So here callMe() function is a callback function.

So, a callback function is a function passed as an argument to another function in order to be called from inside that function.

A callback is a function that is to be executed after another function has finished executing — hence the name ‘call back’.

The most interesting thing about Callback function is that we use them all the time without even realizing it.

Here are some examples:

Callback Function In Event Handling

In web development, callback functions are commonly used to handle events: mouse clicks, key presses, form submissions, and so on.

Also Read: JavaScript – addEventListener() – How To Use It ?

Event listeners are attached to HTML elements and triggered when the corresponding event occurs. The callback function is then executed, allowing the program to respond to the event.

<body>
  <button>Click Me</button>
</body>
const button = document.querySelector("button");

button.addEventListener("click", function() {
  console.log("Button clicked!");
});

//"Button clicked!"

Synchronous Callbacks

Synchronous means the code statements execute immediately after one another in a sequential manner.

Synchronous functions execute one after the other, blocking the execution of other code until they are finished.

function print(number, result) {
    console.log(`${number} is ${result}`);
}

function checkEvenOrOdd(number, callback) {
  const result =  (number % 2 === 0) ? 'Even' : 'Odd';
  callback(number, result);
}

checkEvenOrOdd(56, print);
// 56 is Even

Here the callback is executing immediately and it is not waiting for any asynchronous operation to finish. That’s why it is a synchronous callback.

The above illustrates how synchronous callbacks work. Synchronous callbacks are executed inside the high order functions that use them.

Also Read: Higher Order Functions in JavaScript

When the high order function is done executing, execution of its callback arguments also completes.

Since the high order function has to wait for the completion of synchronous callback execution, synchronous callbacks are also referred to as blocking callbacks — the execution of callbacks block the execution of their caller functions.

Some examples of synchronous callbacks in JavaScript are methods for iterating arrays: forEach, map, filter, reduce, some, every etc.

Asynchronous Callbacks

If a callback is executing after an asynchronous operation has finished then it is an asynchronous callback.

Asynchronous functions can execute concurrently with other code, allowing multiple tasks to be performed at the same time.

The power of asynchronous callbacks lie in JavaScript’s unique runtime model. JavaScript is a single threaded language, meaning that the execution engine of JavaScript only has one call stack.

Then how does asynchronous execution achieved?

The magic is in the API handlers of the JavaScript runtime environment. In the case of web browsers, the APIs are the web APIs. So, tasks of executing asynchronous callbacks are put into the callback queue.

After existing code in the call stack runs to its completion, event loop — a process that is part of the JavaScript engine — brings the callbacks in the callback queue to execution.

Once a callback is run by the execution engine, it is again run to its completion (until the call stack is empty) before the next callback starts to run. This run-to-completion for code on the call stack continues until all the callbacks in the queue are executed.

The asynchronous aspect comes from the fact that a callback is not executed immediately in the high order function, but is put in the callback queue to wait for its turn to be run on the call stack.

The high order function is the one to dispatch the callback task, but not the one to run it.

The most prevalent example of using an asynchronous callback is using the setTimeOut method. Let’s see one example where we will take an order and print it.

function takeOrder() {
    setTimeout(() => {
       return (Math.random() * 10) <= 5 ? 'Coffee' : 'Tea';
    }, 1000);
}

let order = takeOrder();
console.log('Order is for: ' + order);
// Order is for: undefined

Here in the takeOrder function, the setTimeout will run after 1 sec and by that time the console.log statement has already executed therefore printed value of order as undefined.

Now we can resolve this issue if we can log our message to the console only after the data has returned from takeOrder.

This can be done by passing a callback function to takeOrder which will be invoked inside takeOrder function.

function takeOrder(callback) {
    setTimeout(() => {
        const order = (Math.random() * 10) <= 5 ? 'Coffee' : 'Tea';
        callback(order);
    }, 1000);
}

takeOrder((order) => {
    console.log('Order is for: ' + order);
});

// Order is for: Tea

Here, after 1 second, the callback function will be called and the console statement will get executed with the correct order value.

Also, kindly note, the output of takeOrder function may differ in your case as we are using Math.random() to decide order value.

The benefit of the asynchronous callback mechanism is that all the synchronous code is not blocked by asynchronous events. Asynchronous events potentially can take some time to run.

Web applications can run more smoothly and responsively with asynchronous callbacks.

Conclusion

I hope this tutorial helps you understand what callback functions are, how to use them. There are still many things to learn about callback functions so I encourage you to keep practicing and learn by building more projects. You will soon see the beauty and incredible-ness of callback functions.

In summary:

  • A callback function is a function passed as an argument of another function, which will be executed eventually. The callback function executes inside the main function and it is up to the main function to decide when to execute it.
  • A callback function ensures that a function will not run when a task is in progress (for instance, fetching data from an api), but will only run, right after the task has been completed.
  • There are two type of callback functions – synchronous and asynchronous callback functions.
  • Callback functions are used extensively for many purposes, like handling user input, making HTTP requests, and working with timers.

While callback functions can be a powerful tool in a developer’s toolbox, it’s essential to use them carefully and understand the potential pitfalls.

For example, callback functions can lead to callback hell, where the code becomes difficult to read and manage due to excessive nested callbacks.

Developers should also consider using other techniques, such as promises or async/await, to manage complex dependencies between functions.

Overall, callback functions are a crucial part of JavaScript, and every developer should understand how to use them effectively to write efficient, scalable, and maintainable code.

If you have any questions feel free to leave a comment. Thanks for reading and have fun learning! Cheers!

Resource

How useful was this post?

Click on a star to rate it!

Average rating 0 / 5. Vote count: 0

No votes so far! Be the first to rate this post.

We are sorry that this post was not useful for you!

Let us improve this post!

Tell us how we can improve this post?

Similar articles you may like

Sunil Pradhan

Hi there 👋 I am a front-end developer passionate about cutting-edge, semantic, pixel-perfect design. Writing helps me to understand things better.

Add comment

Stay Updated

Want to be notified when our article is published? Enter your email address below to be the first to know.

Sunil Pradhan

Hi there 👋 I am a front-end developer passionate about cutting-edge, semantic, pixel-perfect design. Writing helps me to understand things better.