×

Search anything:

Asynchronous programming in JavaScript

Binary Tree book by OpenGenus

Open-Source Internship opportunity by OpenGenus for programmers. Apply now.

In this article, we have explored Asynchronous programming in JavaScript including ideas like callback, promises, async, await, loop and much more.

Table of Contents


1. Introduction

2. Difference between synchronous and asynchronous function

3. Callback Function

4. Promises

5. Async/Await

6. Loop

7. Final Considerations

Reference


1. Introduction


In a synchronous programming module, the execution of code steps takes place one at a time. In other words, a new function never starts until the previous function step ends.

In contrast, in an asynchronous programming module, several execution steps take place at the same time. If the execution of a step starts, the program does not wait for that step to finish before starting the next step.
In the article, we'll talk about some of the main ways of working asynchronous programming in JavaScript.

2. Difference between synchronous and asynchronous function


In the synchronous method, a function is only executed if the previous step is completed.

In Figure 1, the code execution order starts with the firstStep(), followed by secondStep() and thirdStep(), resulting in JavaScript Java.

function firstStep() {
    console.log("JavaScript")
}

function secondStep() {
    console.log("Java")
}

firstStep();
secondStep();

Figure 1. Code using the synchronous method.

The asynchronous method is not necessarily waiting for the previous execution step to finish before executing the subsequent steps.

In Figure 2, the same code as in Figure 1 is used but with the asynchronous method. In this example, we used the setTimeout function to enqueue the firstStep() that will execute in 0ms, after the event loop (in this case, the secondStep with two console.log statements).
The result returns Java ... JavaScript.

function firstStep(){
    console.log("JavaScript");
}
function secondStep(){
    setTimeout(firstStep, 0);
    console.log("Java");
    console.log("...")
}
secondStep();

Figure 2. Code using the asynchronous method.

3. Callback Function


A callback takes the role of an argument when forwarded to another function.
It runs when some operation completes or when a specific event occurs.
Callback functions are versatile, allowing you to control the order in which functions run, the routing of data between them, and functions depending on circumstances.

In Figure 3, the function callbackTest() takes an argument ca which is called as a method. When executing the code, it returns first Callback invoked and after Function invoked. The result is because the argument invokes first the function myCallback.

function callbackTest (ca) {
    ca()
    console.log('Function invoked')
}

function myCallback () {
    console.log('Callback invoked')
}

callbackTest(myCallback)

Figure 3. Example using callback in an asynchronous method.

4. Promises


The promise is an asynchronous action that can complete at some point and produce value. Along with this argument, it is common to use the then method, which registers a return function when the promise is resolved or an error message when the implementation does not return the expected result within the specification.

In Figure 4, the promise returns after two seconds of implementation the word JavaScript.

const timeout = (duration) => {
    return new Promise((resolve, reject) => {
      setTimeout(resolve, duration)
    })
  }
  
  timeout(2000)
    .then(function() { 
      console.log('JavaScript')
    })

Figure 4. Illustrative example with Promises returning the result after 2 seconds of code implementation.

Furthermore, promises are used to solve problems within asynchronous code.
The biggest challenge in developing asynchronous JavaScript code is coordinating the order of execution of the functions and solving the possible errors that might occur.

Within asynchronous processing, it is not possible to know the part of the code where the error occurred. At a minimum, one console message can be generated to solve possible errors.

Promises are used to encapsulate problems by providing ways to organize callback functions.

A promise is an object that serves as a "gap" for a value. This value is usually the result of an asynchronous operation.

When an asynchronous function is called it can immediately return a Promise object. Using this object, you can register callbacks that will execute when the operation is successful or with errors.

Promises are also an efficient tool for solving the "callback hell", which occurs when you use multiple callbacks inside other callbacks to get asynchronous returns from multiple functions. This makes the code polluted and confused.
In figure 5, the code generates an error if the number drawn is smaller than the possibleError.

function test(value, possibleError){
    return new Promise((solve, reject) =>{
        if(Math.random() < possibleError){ 
            reject('Error Detected!')
        }else {
            solve(value)
        }
    })
}

Figure 5. The first part of the code for the identification of an error in the execution.

Before creating a way to resolve the error. The error is recognized and handled within then so the catch will not be called. However, catch is used to catch errors within the code stream (Figure 6).

test('Testing...', 0.9)
    .then(v => `Valor: ${v}`)
    .then(v => consol.log(v),
        err => console.log(`Alert: ${err}`)
        )
    .catch(err => console.log(`Erro: ${err}`))
    .then(() => console.log("Test Finished!"))

Figure 6. The last part of code to identify a runtime error containing then and catch.

As a final result (Figure 7):

Alert: Error Detected!
Test Finished!

Figure 7. The result generated with error message return.

5. Async/Await


This tool works with code based on hidden Promises to code executes easily and fast.
By defining a function as async, you can use the word await before any expression that returns a promise. In this way, the execution of the async function is paused until the Promise is resolved.

The await keyword takes a Promise and turns it into a return or error value.
In other words, if the code is successfully terminated it returns a value. Otherwise, if Promise is rejected it returns the error thrown by the exception.

In Figure 8, the async/await keywords are used, which returns an error in case of promise rejection. In this case, the code resulted in the word OpenGenus.

function show(result) {
    console.log(result);
  }
  async function myTest() {
      return "OpenGenus";
    }
  myTest().then(
    function(value) {show(value);
    },
    function(error) {show(error);
    });

Figure 8. Example using async/await.

6. Loop


The loop allows the same function to be used until the imposed restrictions are met.
In this process, the function does not need to be repeated multiple time.

In Figure 9, the number 123 is repeated 4 times, with an interval of 2000 ms.
The generated result is because the n variable is shared by all closures.

function print(y) {
    for (var n = 0; n < y; n++) {
      setTimeout(function () {
        console.log(n);
      }, (y - n) * 2000);
    }
  }
  
  print(123);

Figure 9. Example de loop utilizando o método assíncrono.

7. Final Considerations


The software's modern design is based on asynchronous programming, allowing programs to execute multiple requests at the same time.

An example of an asynchronous action in our daily lives is the possibility of opening several browser windows at the same time or instead of one at a time.
For more information and details on asynchronous programming, see the freeCodeCamp website.

With this article at OpenGenus, you must have the complete idea of Asynchronous programming in JavaScript.

Asynchronous programming in JavaScript
Share this