Open In App

How to return the response from an asynchronous call in JavaScript ?

Improve
Improve
Like Article
Like
Save
Share
Report

JavaScript is a single-threaded programming language and asynchronous programming is a foundational concept around which the language is built. There are three methods to deal with Asynchronous calls built into JavaScript as shown below:

  • Callback Functions
  • Promises and Promise Handling with .then() and .catch() method
  • ES6+/ESNext style async functions using await

In this article, we will discuss how to deal with asynchronous calls in all of the above-mentioned ways. We will use the request module provided in Node.js to request JSON data from the website DOG CEO API which returns an URL link for a randomized dog picture in JSON format.

  1. Using a Callback function:




    // Callback method
    const request = require('request');
      
    function callback(res, body) { 
        console.log(JSON.parse(body));
    }
      
    function getData(callback) {
      
        // Using the request module to request
        // data asynchronously
        request(url, (err, res, body) => {
            if (err) throw err;
            callback(res, body);
        });
    }
      
    // Here we call the getData function
    // with the callback function 
    getData(callback);
    console.log('asynchronous is awesome');

    
    

    Output:

    asynchronous is awesome {
      message: 
    'https://images.dog.ceo/breeds/vizsla/n02100583_11450.jpg',  
      status: 'success'
    }
    

    Explanation: In this method, we request the API for JSON data and perform functions on the data using callback functions. For purposes of understanding, we simply log the data received to the console, but various other functions can be performed. This entire process happens asynchronously. The command console.log('asynchronous is awesome'); although placed after the call to the function getData, is performed before getData is completed.

  2. Using Promises with .then() and .catch() method:




    // Promise with then catch
    const promise = new Promise((resolve, reject) => {
        request(url, (err, res, body) => {
            if (err) return reject(err);
            try {
                resolve(JSON.parse(body));
            } catch(error) {
                reject(error);
            }
        });
    });
      
    promise.then((data) => {
        console.log(data);
    })
    .catch((err)=>{
        console.error(err);
    });
      
    console.log('asynchronous is awesome');

    
    

    Output:

    asynchronous is awesome {
      message:
    'https://images.dog.ceo/breeds/pointer-germanlonghair/hans2.jpg',
      status: 'success'
    }
    

    Explanation: The request module does not natively return promises. Hence we use the promise constructor to wrap the possible response received from the HTTP request into a native promise. This promise is then handled with .then() and .catch() method. The advantages of using this method are manifold. Firstly, resolving promises with .then() and .catch() method is the best practice for error handling and helps us to write code with an error first mindset. Secondly, JavaScript modules are adapting to support promises and are discarding the older callback style error handling. Newer modules like Axios, fetch, etc only support promises. Again, Promises are a relatively newer way of writing asynchronous code. This is proved by the fact that the command console.log('asynchronous is awesome'); although placed after the call to the promise handler, is performed before the promise is completed.

  3. ES6+/ESNext style async functions using await:




    const getData = async () => {
        let data = await new Promise((resolve, reject) => {
            request(url, (err, res, body) => {
                if (err) return reject(err);
                try{
                    resolve(JSON.parse(body));
                } catch(error) {
                    reject(error);
                }
            });
        });
      
        try{
            console.log(data);
        }
        catch(err){
            console.error(err);
        }
    }
      
    getData();
    console.log('asynchronous is best');

    
    

    Output:

    asynchronous is awesome {
      message: 
    'https://images.dog.ceo/breeds/sheepdog-shetland/n02105855_15196.jpg',
      status: 'success'
    }
    

    Explanation: Async functions in Javascript allow us to stick to conventional programming strategies such as using for, while, and other methods that are otherwise synchronous in nature and cannot be used in Javascript. In this example, we wrap the possible response returned from the HTTP request in a promise. Since the promise takes a certain amount of time to either get resolved or rejected, we use the await keyword to wait for the promise to return a response. It is best practice to use a try()/catch() sequence to handle the response received from the promise after using await, to help us handle errors if any. Although synchronous code can be written in the try()/catch() sequence, the async function executes asynchronously, which is proved by the fact that the command console.log('asynchronous is awesome'); although placed after the call to the function getData, is performed before the async function is completed.



Last Updated : 01 Jul, 2020
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads