A Guide to Callback Functions in JavaScript

A callback function in JavaScript is a function that’s called after the first function has completed its task. Learn more about how they’re used and when to use them.

Written by Akshay Kumar
Person dialing a number on a rotary phone
Image: Shutterstock / Built In
Brand Studio Logo
UPDATED BY
Brennan Whitfield | Nov 20, 2024

A callback function is a function in JavaScript that is called (or invoked) by the first function after the first function has completed its task. It’s a function that receives input from another function. 

Callbacks are often used when handling asynchronous events like network requests or file I/O. It’s a means to guarantee that certain code won’t run until a given task has been completed. Callbacks can be an effective tool for asynchronous programming. They give you the option of separating the code that executes asynchronous operations from the code that deals with the outcomes of such operations.

Callback Functions in JavaScript Explained

Callback functions are functions that are called after the first function completes its task. They are often used to handle asynchronous events and make your code more readable. 

This can make your code more modular and understandable. I’ll explain how to use callback functions and when to use them.

 

A tutorial on how to use callbacks in JavaScript. | Video: Code With Ania Kubów

What Are Callback Functions?

Callback functions are functions that are deployed after the first function completes its task. They are frequently deployed in scenarios like managing asynchronous actions, such as retrieving data from a server, handling events and ensuring proper operation sequencing.

For example, the setTimeout method in Node.js and browsers waits a specified amount of milliseconds, one second is equal to a thousand milliseconds, before calling a function.

setTimeout() method code in JavaScript
setTimeout() method code in JavaScript. | Image: Akshay Kumar

In general, waiting is not a highly important type of work, although it can be helpful when performing tasks like updating an animation or determining whether anything is taking longer than expected.

When using callbacks to execute several asynchronous actions consecutively, you must keep sending new functions to handle the continuation of the computation after the actions.

More on JavaScriptHow to Make JavaScript Sleep or Wait

 

Why Are Callback Functions in JavaScript Important?

Callback functions are important in JavaScript because they let you create asynchronous code that doesn’t block the main thread of execution. This enables you to perform other tasks, such as user interface (UI) updates or other API calls, while an asynchronous action is executing.

JavaScript callback functions are important for the following reasons:

  • They allow you to handle events. Events in your JavaScript program include things like a user pressing a button or a network request concluding. Callbacks allow events to be handled as they happen.
  • You can use them to send asynchronous API calls. Many APIs are asynchronous, which means they don’t immediately return a value. They instead give back a promise or a callback method. When the API call is finished, the callback function is invoked.
  • You can use them to enhance your code’s performance. Callbacks enable you to multitask while an asynchronous action is running, which can help your code execute faster.
  • Callback functions can be used to manage the flow of asynchronous operations, preventing the infamous “callback hell.” This is a situation where deeply nested callbacks make code hard to read and maintain.
  • Closures, which allow functions to “remember” the scope in which they were generated, are frequently used by callback functions. This has the potential to be very effective at preserving state and encapsulating behavior.
  • Higher-order functions, or functions that can take other functions as inputs or return other functions as values, are based on the concept of callbacks. This functional programming pattern is effective.

 

When to Use a Callback Function

When you need to take action after an asynchronous process has finished, callbacks can be helpful. As an illustration, you could utilize a callback function to:

  • Update the UI after a network request has completed.
  • Process data after a file has been read.
  • Make another API call after the results of the first API call have been received.

When you want to separate the code that executes an asynchronous operation from the code that handles the results of the operation, you should generally use a callback function. Your code may become more modular and understandable as a result. 

Callback functions also encourage improved error handling and permit gentle degradation in the event of errors during asynchronous processes. You can efficiently control the flow of your program by enclosing the handling of results or errors within a callback, ensuring that it reacts correctly to diverse outcomes without interfering with the functionality of the entire application.

Below are some specific cases where you might want to use a callback function:

  • When making an asynchronous API call.
  • When listening for events.
  • When running a long-running task.
  • When working with promises.

For example, a callback function can be used to update the UI after a network request has completed:

Code example for a callback function used to update the UI after a network request.
Code example for a callback function used to update the UI after a network request. | Image: Akshay Kumar

The button in this example has an event listener added to it using the addEventListener() method. When the button is clicked, a callback function called the event listener is activated. The /api/usersendpoint is then accessed asynchronously by the callback function. The callback function updates the UI with the user's data after the API call is finished.

More on JavaScriptTop 50 JavaScript Interview Questions with Example Answers

 

Synchronous vs. Asynchronous Callback Functions

Synchronous callback functions execute instantly, but asynchronous callback functions execute at a later time.

The sequence in which synchronous callbacks are defined is followed when they are executed. This implies that the first callback will be processed ahead of the second callback if a function calls two synchronous callbacks. The order in which asynchronous callbacks are executed is random. You can’t predict when the asynchronous callback will be invoked as a result.

Synchronous callbacks are frequently used when something needs to be done right away, such as updating the user interface or calling an API. When you need to do a task that requires some time, such as reading a file or sending a network request, asynchronous callbacks are frequently utilized. Because they follow a sequential flow, synchronous callbacks are easier to understand. However, in situations with lengthy activities, they can result in blocking a behavior.

For managing tasks that require time, such as network requests, asynchronous callbacks are crucial. They let a program carry out additional tasks while awaiting the completion of these operations, which can result in applications that are more responsive and effective. Let’s look at an example of both synchronous and asynchronous functions.

Synchronous Callback

In this example, we have two functions: greet and sayGoodbye. The greet function takes two arguments: name (a string) and callback (a function). It logs a greeting message using the provided name and then calls the callback function.

The sayGoodbye function simply logs a "Goodbye!" message.

synchronous function example with hello goodbye code.
Synchronous function code example. | Image: Akshay Kumar

When we call greet("Alice", sayGoodbye), it will output:

synchronous function callback output "hello, Alice! Goodbye"
Synchronous function output. | Image: Akshay Kumar

The sayGoodbye function is called immediately following the greet function’s completion, making it an example of a synchronous callback function. Asynchronous execution of the callback function means that it is called and finished before the following line of code is run.

Asynchronous Callback

In this example, the asyncOperation function uses setTimeout to simulate an asynchronous task. The callback is executed after a delay of 1 second.

asynchronous callback function code example
Asynchronous callback function code input. | Image: Akshay Kumar

Output:

Asynchronous callback function output.
Asynchronous callback function output. | Image: Akshay Kumar

 

Callback Function in JavaScript Example

Here are some examples of callback functions in JavaScript:

setTimeout()

setTimeout() takes a callback function as an argument and executes the callback function after a specified amount of time.

It takes two arguments: the first is the callback function to be executed, and the second is the time delay in milliseconds before the callback is invoked.

In the given example, if you have a setTimeout() set to 1000 milliseconds (or 1 second), it means that the provided callback function will be executed after 1 second.

setTimeout() callback function code example
SetTimeout() callback function code example. | Image: Akshay Kumar

addEventListener()

This function takes two arguments: an event name and a callback function. The callback function is executed when the event occurs.

In this example, querySelector('button') selects the first “<button>” element in the document. The subsequent addEventListener function adds an event listener for the "click" event on this button.

When the button is clicked, the provided callback function will be executed, logging "Button clicked!" to the console along with the event object.

addEventListener() callback function code example
AddEventListener() callback function code example. | Image: Akshay Kumar

Promise.then()

This method takes a callback function as an argument and executes the callback function when the promise is resolved.

In this example, we create a Promise (myPromise) that simulates an asynchronous operation using setTimeout.  Inside the Promise, after a one-second delay, we resolve the Promise with the message 'The promise was resolved!'. We then chain a then() method onto myPromise. The first argument of then() is a function that will be executed if the Promise is resolved.

Promise.then() callback function code example
Promise.then() callback function code example. | Image: Akshay Kumar

Asyc/await 

Asynchronous programming in JavaScript frequently entails constructing and managing Promises, which can result in complicated and challenging-to-read code. Async and await are two keywords that JavaScript introduced to streamline this procedure.

In this example, this is an async function named fetchData. It is responsible for fetching data from a specified API endpoint. Inside the function, it uses a try...catch block to handle any potential errors that may occur during the fetch operation. 

It uses await to pause the execution of the function until the fetch operation is complete. This allows you to work with the result once it's available. The response is obtained in the form of a Response object, which needs to be converted to JSON using response.json() to extract the actual data.

Async/await callback function code example.
Async/await callback function code example. | Image: Akshay Kumar

This example demonstrates how async/await simplifies asynchronous code, making it appear more like synchronous code. The await keyword allows you to work with Promises in a more straightforward and linear manner.

More on JavaScriptGuide to the JavaScript Array Filter() Method

 

Troubleshooting Common Issues with a Callback Function

The following are some common callback function issues and approaches:

  • The callback function is not being called. If the callback function is not defined properly or is not provided to the appropriate function, this may occur. Make sure that the callback function is defined properly and that the right function receives it.
  • The callback function is being called too late. If the asynchronous operation has already ended, then this can occur. Ensure that the callback function is invoked following the conclusion of the asynchronous action.
  • The callback function is being called too early. If the asynchronous operation hasn’t finished yet, this might occur. Don't call the callback function until the asynchronous action has finished.
  • Forgetting to pass the callback function. When invoking a function that expects a callback function, double-check that you are indeed supplying that function. Make sure that the callback parameter is present in the function signature. Make sure that the callback is being supplied as an argument by checking the function call twice.
  • Error handling. If the callback function you're using handles errors, ensure it thoroughly screens for and responds to any issues that might arise. Make sure that the callback function has the proper logic for managing errors, such as looking for error objects and treating them properly.
  • Debugging. Sometimes, the problem may not be with the callback function specifically, but with other areas of the code. To analyze variables and track the execution path, use debugging tools like console.log() commands, breakpoints and browser developer tools.

Frequently Asked Questions

A callback function passes an argument to another function, allowing the first function to “call back” and run the second function at a later time. Callback functions are used to execute code in response to an initial function completing a task or meeting a certain condition.

The two types of callback functions are synchronous and asynchronous callbacks.

  • Synchronous callback function: called and executed immediately after a higher-order function using the callback is run; blocks further operations until it completes.
  • Asynchronous callback function: called and executed at a later time, allowing the higher-order function using the callback to continue without waiting; is non-blocking.

No — a callback is not the same as recursion, and callback functions are different from recursive functions in JavaScript. A callback is a function passed to another function to be executed later — often used in asynchronous tasks like data fetching and network requests. Recursion, on the other hand, is when a function calls itself to solve a problem by breaking it into smaller subproblems. This is commonly seen in tasks like calculating factorials and traversing trees. Although callbacks can sometimes be recursive, they are generally used for different purposes.

Callback functions are meant to be executed after another function is run first, while a regular function can be executed immediately and doesn’t have to rely on another function to run.

Explore Job Matches.