skip to Main Content

Why this async/await version of asynchronous program in JS doesn’t give any output?

async-await version:

const https = require('https');

async function getDataFromServer() {
  try {
    const response = await https.get('https://jsonplaceholder.typicode.com/posts/1');
    let data = '';
    response.on('data', (chunk) => {
      data += chunk;
    });
    response.on('end', () => {
      console.log(data);
    });
  } catch (error) {
    console.error(error);
  }
}

getDataFromServer();

whereas other two versions work?

callback version:

const https = require('https');

function getDataFromServer(callback) {
  https.get('https://jsonplaceholder.typicode.com/posts/1', (response) => {
    let data = '';
    response.on('data', (chunk) => {
      data += chunk;
    });
    response.on('end', () => {
      callback(data);
    });
  }).on('error', (error) => {
    console.error(error);
  });
}

getDataFromServer((data) => {
  console.log(data);
});

promise version:

const https = require('https');

function getDataFromServer() {
  return new Promise((resolve, reject) => {
    https.get('https://jsonplaceholder.typicode.com/posts/1', (response) => {
      let data = '';
      response.on('data', (chunk) => {
        data += chunk;
      });
      response.on('end', () => {
        resolve(data);
      });
    }).on('error', (error) => {
      reject(error);
    });
  });
}

getDataFromServer().then((data) => {
  console.log(data);
}).catch((error) => {
  console.error(error);
});

Thank you.

I tried three versions of simple asynchronous programming examples in JavaScript (with callback, promise, and async-await), but I cannot figure out why the async/await version cannot give the same result as the other two versions? I.e., nothing appears in console window.

2

Answers


  1. Why this async/await version of asynchronous program in JS doesn’t give any output?

    Because you’re just using https.get() wrong. That function REQUIRES a callback in order to get a response back. It does not support promises in any way.

    Thus, when you do this:

    const response = await https.get('https://jsonplaceholder.typicode.com/posts/1');
    

    That await isn’t doing anything useful because https.get() does not return a promise – instead it returns a http.ClientRequest object that you would write to if it was a POST or some other type of request that you need to write a body with. await is ONLY useful when awaiting a promise that resolves to the value you want. So, since you don’t pass a callback, you never get the response object and you are, instead, attaching your event handlers to the request object which never emits a data or end event and thus "nothing" seems to happen. In reality, the request is sent, but you don’t have the right listeners to get the response.

    Instead, you have to get the response object by passing a callback function just like you do in your other two examples.


    Note: https.get() is a pretty low level API that doesn’t inherently support promises. For code that just wants to send a request and get the whole response using promises, it will save you code to use a higher level API that has built-in promise support. Popular options are:

    fetch()
    got()
    axios()
    

    As of nodejs v18, the same implementation of fetch() as used in browsers is now present in nodejs:

    async function getDataFromServer() {
        const response = await fetch('https://jsonplaceholder.typicode.com/posts/1');
        const results = await response.json();
        console.log(results);
    }
    
    getDataFromServer().catch(err => {
        console.log(err);
    });
    

    My personal favorite is the got() library (I just like the programming interface and it is has a rich feature set).

    const got = require('got');
    
    async function getDataFromServer() {
        const result = await got('https://jsonplaceholder.typicode.com/posts/1').json();
        console.log(result);
    }
    
    getDataFromServer().catch(err => {
        console.log(err);
    });
    
    Login or Signup to reply.
  2. I assume, you are using nodejs https module to fetch the data. It support callback only.

    To make into async/await, call your promise version this way

    const https = require('https');
    
    function getDataFromServer() {
      return new Promise((resolve, reject) => {
        https
          .get('https://jsonplaceholder.typicode.com/posts/1', (response) => {
            let data = '';
            response.on('data', (chunk) => {
              data += chunk;
            });
            response.on('end', () => {
              resolve(data);
            });
          })
          .on('error', (error) => {
            reject(error);
          });
      });
    }
    
    //wrap your promise based version as async call
    async function getDataFromServerAsync() {
      // return the response
      return await getDataFromServer();
    }
    
    //call the async function
    getDataFromServerAsync().then((resp) => {
      console.log('Response received: ', resp);
    });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search