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

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:
    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    // 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');

    chevron_right

    
    

    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:
    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    // 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');

    chevron_right

    
    

    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:
    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    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');

    chevron_right

    
    

    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.

full-stack-img




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.


Article Tags :

Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.