DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Because the DevOps movement has redefined engineering responsibilities, SREs now have to become stewards of observability strategy.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Related

  • Exploring Intercooler.js: Simplify AJAX With HTML Attributes
  • The Cypress Edge: Next-Level Testing Strategies for React Developers
  • How to Build Scalable Mobile Apps With React Native: A Step-by-Step Guide
  • Mastering React App Configuration With Webpack

Trending

  • Building a Real-Time Audio Transcription System With OpenAI’s Realtime API
  • Analyzing Techniques to Provision Access via IDAM Models During Emergency and Disaster Response
  • Enhancing Business Decision-Making Through Advanced Data Visualization Techniques
  • Can You Run a MariaDB Cluster on a $150 Kubernetes Lab? I Gave It a Shot
  1. DZone
  2. Coding
  3. JavaScript
  4. JavaScript Callback Functions: An In-Depth Guide

JavaScript Callback Functions: An In-Depth Guide

Holla back with callbacks!

By 
Nilesh Sanyal user avatar
Nilesh Sanyal
DZone Core CORE ·
Oct. 18, 19 · Tutorial
Likes (4)
Comment
Save
Tweet
Share
15.2K Views

Join the DZone community and get the full member experience.

Join For Free

Image title

JavaScript callback functions; another important concept you must need to understand to become a successful JavaScript developer. But I am sure that after reading this article thoroughly you will be able to overcome any obstacles you previously had with callbacks.

Before we begin, let's first make sure that our understanding of functions in general is solid. 

A Quick Recap: Javascript Functions

What Is a Function?

A function is a logical building block inside of which a set of codes are written in order to perform a specific task. Practically, functions allow writing code in a more organized way that is also easy to debug and maintain. Functions also allow code reuse.

You define function once and call it when you need to without writing the same codes again and again.

You may also like: Javascript Callback Functions.

Declaring a Function

We talked a little about what a function is. Now, let's see how to declare a function in javascript.

  1. Using Function Constructor: In this approach, the function is created with the help of a "Function" constructor. Technically, this approach is less efficient than declaring a function with the function expression syntax and function declaration statement syntax.

  2. Using Function Expression: Typically, this approach is the same as a variable assignment. In simple words, the function body is considered as an expression, and that expression is assigned to a variable. Functions defined with this syntax can be either named or anonymous.

    A function that has no name is known as an anonymous function. An anonymous function is self invoked, which means it calls itself automatically. This behavior is also known as immediately invoked function expression (IIFE).

  3. Using Function Declaration Statement: Actually, this method is the old school method that is used commonly in JavaScript. Here, after the keyword "function" you have to specify the name of the function. After that, if the function accepts multiple parameters or arguments, you need to mention them too. Although, this part is completely optional.

    In the body of the function, the function must return a value to the caller. After a return statement is found, the function will stop executing. Inside the function, the parameters will act as a local variable.

    Also, the variables that are declared inside the function will be local to that function. Local variables can be accessed within that function only, so variables with the same name can easily be used in different functions.

Invoking a Function

The function declared before will be invoked when any one of the following occurs:

  • When an event occurs, for example, the user clicks on a button, or the user selects some option from the dropdown list, etc.
  • When the function is called from the javascript code.
  • The function can also be invoked automatically, we already discussed that in an anonymous function expression.

The () operator invokes the function.

What Is a Callback Function?

As per MDN: A callback function is a function passed into another function as an argument, which is then invoked inside the outer function to complete some kind of routine or action.

Let me clarify this with simple words, a callback function is a function that will be executed just after another function has finished executing. The callback function is a function that is passed as an argument to another JavaScript function. That callback function is executed inside of the function it was passed into.

In JavaScript, functions are treated as first-class objects; by first-class object, we mean that a number or a function or a variable can be treated as same as any other entity in the language. Being a first-class object, we can pass functions to other functions as variables, and functions can be returned from other functions too.

Functions that can do this are known as higher-order functions. A callback function is actually a pattern. The word "pattern" means some sort of proven methodology to solve a common problem in software development. There it is better to call the use of callback function as a callback pattern.

Why We Need Callback

Client-side JavaScript runs in the browser, and the main browser process is a single-threaded event loop. If we try to execute long-running operations within a single-threaded event loop, the process is blocked. This is technically bad because the process stops processing other events while waiting for your operation to complete.

For example, the "alert" statement is considered as one of the blocking codes in javascript in the browser. If you run alert, you can no longer do any interaction within the browser until you close the alert dialog window. In order to prevent blocking on long-running operations, a callback is used.

Let's dive deep so that you will understand exactly which scenario a callback is used in.

Get and display message functions

In the above code snippet, getMessage() function is executed at first and then displayMessage() is executed. Both displayed a message in the browser's console window and both of them executed immediately.

In certain situations, some code is not executed immediately. For example, if we assume that getMessage() function performs an API call where we have to send the request to a server and wait for the response. Then how we will be able to deal with it?

How To Use Callback Functions

Rather than telling you about the syntax of JavaScript callback functions, I think it would be better if we try to implement a callback function on our previous example. The code snippet is shown below in the following screenshot.

Display message used in a callback function

In order to use a callback function, we need to perform some sort of task that will not be able to display results immediately. To emulate this behavior, we are using JavaScript's setTimeout() function. That function will take two seconds to display the message "Hi, there" to the console window.

After this message is displayed, then "Displayed message" will be shown in the console window of the browser. In this scenario, at first, we are waiting for the getMessage() function. After this function is executed successfully, we execute the displayMessage() function.

How Callbacks Work

Let me explain what actually happened behind the scene in the previous example.

As you can see from the previous example, in the getMessage() function, we are passing two arguments. The first argument is the msg variable, which gets displayed in the browser's console window, and the second argument is the callback function.

Now, you may wonder why the callback function is passed as the argument — to implement a callback function, we must pass a function as an argument to another function.

After getMessage() finishes it's task, we are calling the callback function. After that, when we are calling getMessage() function, we passed the reference to the  displayMessage() function, which is treated as a callback function.

Note that, when getMessage() function is called, we are only passing the reference to the displayMessage() function. That's why, you will not see the function invoke operator i.e, "()" beside it.

Are Javascript Callbacks Asynchronous?

JavaScript is considered as a single-threaded scripting language. By single-threaded we mean that JavaScript execute one code block at a time. When JavaScript is busy executing one block, it is not possible for it to move to the next block.

In other words, we can say that the JavaScript code is always blocking in nature. But this blocking nature prevents us from writing code in certain situations when we are not able to get the immediate results after running some specific tasks.

I am talking about tasks such as the following.

  • Sending API call to certain endpoints for getting data.
  • Sending network requests to get some resources (for example, text file, image file, binary file, etc. ) from a remote server.

To handle these situations, we must write asynchronous codes and the callback function is one approach to deal with these situations. So, callback functions are asynchronous in nature.

Javascript Callback Hell

Callback hell occurs when multiple asynchronous functions are executed one after another. It is also known as the pyramid of doom.

Let's assume, you want to get a list of all Github users. Then, among the users, you want to search for only top contributors for a JavaScript repository. Then, among the users, you want to get details of the person whose name is John.

To implement this functionality with the help of callbacks, the code snippet will be similar as shown below.

http.get('https://api.github.com/users', function(users) {
  /* Display all users */
  console.log(users);
  http.get('https://api.github.com/repos/javascript/contributors?q=contributions&order=desc', function(contributors) {
  /* Display all top contributors */
    console.log(contributors);
    http.get('https://api.github.com/users/Jhon', function(userData) {
    /* Display user with username 'Jhon' */
      console.log(userData);
    });
  });
});


From the above code snippet, you can see that the code becomes harder to understand, harder to maintain and also harder to modify. This happens due to the nesting of all the callback functions.

How Do You Stop Callback Hell?

Multiple techniques can be used to avoid callback hell there are as follows.

  1. By using promises.
  2. With the help of async-await
  3. By using async.js library

Using Async.js Library

Let's talk about working with the async.js library in order to avoid callback hell.

As per the official website of async.js : Async is a utility module which provides straight-forward, powerful functions for working with asynchronous JavaScript.

Async.js provides near about 70 functions in total. For now, we will discuss only two of them i.e, async.waterfall() and async.series().

async.waterfall()

This method is useful when you want to run some tasks one after the other and then pass the result from the previous task to the next task. It takes an array of functions "tasks" and a final "callback" function that is called after all functions in "tasks" array have completed or a "callback" is called with an error object.

var async = require('async');
async.waterfall([
    function(callback) {
      /*  
        Here, the first argument value is null, it indicates that
        the next function will be executed from the array of functions.
        If the value was true or any string then final callback function
        will be executed, other remaining functions in the array 
        will not be executed.
      */
        callback(null, 'one', 'two');
    },
    function(param1, param2, callback) {
        // param1 now equals 'one' and param2 now equals 'two'
        callback(null, 'three');
    },
    function(param1, callback) {
        // param1 now equals 'three'
        callback(null, 'done');
    }
], function (err, result) {
    /*
      This is the final callback function.
      result now equals 'done'
    */
});


async.series()

This function is helpful when you want to run functions, and then you need to get the results after all the functions have executed successfully. The main difference between async.waterfall() and async.series() is that async.series() doesn't pass the data from one function to another function.

async.series([
    function(callback) {
        // do some stuff ...
        callback(null, 'one');
    },
    function(callback) {
        // do some more stuff ...
        callback(null, 'two');
    }
],
// optional callback
function(err, results) {
    // results is now equal to ['one', 'two']
});


Javascript Callback vs Closure

Closure

In technical terms, closure is the combination of a function that is bundled together having references to its surrounding state.

Simply put, a closure allows access to the outer function's scope from an inner function.

To use a closure, we need to define a function inside another function. Then, we need to return it or pass it to another function.

Callback

Conceptually callbacks are similar to closure. A callback is basically where a function accepts another function as an argument.

Final Words

I hope this article clears all your doubts on javascript callback functions. If you find this article helpful, share it among others.


Further Reading

  • Object-Oriented JavaScript.
  • Functional Programming in JavaScript.
  • Debugging JavaScript.
JavaScript

Published at DZone with permission of Nilesh Sanyal. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Exploring Intercooler.js: Simplify AJAX With HTML Attributes
  • The Cypress Edge: Next-Level Testing Strategies for React Developers
  • How to Build Scalable Mobile Apps With React Native: A Step-by-Step Guide
  • Mastering React App Configuration With Webpack

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!