randombits
randombits

Reputation: 48450

Does client-side code that calls an an async function need to use await?

Imagine the following hypothetical, minimal implementation of a function that does a simple HTTP GET request using axios. This uses await/async as depicted in the post.

const axios = require('axios')

exports.getStatus = async id => {
  const resp = await axios.get(
    `https://api.example.com/status/${id}`
  )

  return resp
}

Is the promise not resolved using await? Is it required that the client uses await as depicted below? Is it safe to assume that anytime a client consumes an async function, that it also needs to use await when calling the function?

// client
const { getStatus } = require('./status')

const response = await getStatus(4)

Upvotes: 2

Views: 3456

Answers (3)

tksilicon
tksilicon

Reputation: 4426

No you don’t have to. The async function executes and waits until it returns error or completes execution and return a response!

Upvotes: 0

junvar
junvar

Reputation: 11574

Short answer, no. Labelling a function async means 2 things:

1) you're allowed to use await inside the function.

2) The function returns a promise; i.e. you can use await on its return value, or you can use .then, or Promise.all, or even ignore the return value, or anything else you can do with promises.

E.g. you could do the following which (depending on your use case) could be more performant because it needs not wait for the response to continue.

// client
const { getStatus } = require('./status')

const response4 = getStatus(4);
const response5 = getStatus(5);

// do stuff that don't rely on the responses.

response4.then(response => myOutput.setFirstOutput(response));
response5.then(response => myOutput.setSecondOutput(response));

Btw, your first snippet is redundant with its usage of await; it's equivalent to

const axios = require('axios')

exports.getStatus = id =>
  axios.get(`https://api.example.com/status/${id}`);

This is because return await promise is equivalent to return promise, both return the same promise. There is one exception regarding rejected promises. Awaiting a rejected promise will throw an exception (which you can catch with a try/catch block), whereas directly returning a rejected promise will not throw an exception but you should still handle the rejection (with a .catch clause). To illustrate:

let promise = new Promise(resolve => setTimeout(() => resolve('resolved after 2 seconds'), 2000));

let returnPromise = () => promise;
let returnAwaitPromise = async () => await promise;

returnPromise().then(value => console.log('returnPromise,', value));
returnAwaitPromise().then(value => console.log('returnAwaitPromise,', value));

Upvotes: 3

Tomasz Kasperczyk
Tomasz Kasperczyk

Reputation: 2093

No, you don't need to use await. An async function returns a Promise that should be resolved. Instead of using await, you can simply call .then() like so:

// client
const { getStatus } = require('./status');

getStatus(4).then((response) => {
    //Do something with the response
}).catch((error) => {
    //Handle possible exceptions
});

Below I'll address your question from the comments. The getStatus function could be rewritten like this:

exports.getStatus = (id) => {
    return new Promise((resolve, reject) => {
        axios.get(`https://api.example.com/status/${id}`).then((resp) => {
            resolve(resp);
        }).catch((error) => {
            reject(error);
        })
    });
}

It would act exactly the same as in your version. When you call asynchronous functions in series, you have to resolve each of the returned Promises. In your case, there are two of them - the one returned by axios.get and the one returned by getStatus.

Upvotes: 0

Related Questions