User 5842
User 5842

Reputation: 3029

Async/Await Nuances

I am trying to understand some of the nuances of async/await in Javascript and was hoping I can get some help here.

Suppose I have the following functions:

async function sum(a, b) {
    return await adder(a, b);
}

function sum(a, b) {
    return adder(a, b);
}

It's my understanding that the return values of the above functions are the same, due to async returning a promise, or wrapping non-promises.

Suppose adder returns a number. The first function will first resolve the await adder which will be a number, but then the async will wrap it as a Promise<number>.

Similarly, for the second one, a regular Promise<number> will be returned.

Am I correct in saying this?

Upvotes: 1

Views: 60

Answers (3)

dor272
dor272

Reputation: 738

async functions always return promises. so assuming adder is async function both of the functions return promises. in function 1 it will wait for the promise returned from adder to be resolved, once resolved it will return the number value, but async function always wraps the return value in promise if it isn't the in first place. so it returns a promise. in function 2 it is because it returns the return value of adder which is a promise;

think of the return clause in async function as resolving the promise it returns.

Upvotes: 0

xdeepakv
xdeepakv

Reputation: 8125

Please refer to the inline comment for details.

async function sum(a, b) {
  return a + b;
}
const promise = sum(1, 2);

// Here calling sum will return promise.
// Whatever you return it will be wrraped in promise[for simplicity]
// Above code is similar to

function sum1(a, b) {
  return Promise.resolve(a + b);
}

// Assuming adder funtion is async function

function adder(a, b) {
  return new Promise((r) => {
    setTimeout(r, 1000, a + b);
  });
}

// So calling adder
async function sum2(a, b) {
  return await adder(a, b);
}

// Equivalent to

async function sum3(a, b) {
  const data = await adder(a, b);
  return Promise.resolve(data);
}

// sum3 will return promise
sum3(1, 2).then(console.log);

// which is equivalent to

async function sum4(a, b) {
  return adder(a, b);
}
// sum4 will return promise
sum3(1, 2).then(console.log);

Upvotes: 0

T.J. Crowder
T.J. Crowder

Reputation: 1074138

It's my understanding that the return values of the above functions are the same...

Not quite, no, but you seem to know that:

Suppose adder returns a number. The first function will first resolve the await adder which will be a number, but then the async will wrap it as a Promise<number>.

Similarly, for the second one, a regular Promise<number> will be returned.

No, not if adder returns a number. The second one (the non-async sum) will return a number, not a Promise<number>, because neither it nor adder is async.

If adder returns a native Promise<number>, then the return values of async function sum and function sum are the same, although there may be a slight difference in timing.

There's never any real reason to use return await x unless you have it wrapped in a try/catch and you want to handle any error from x locally in the function. Otherwise, just return is sufficient, even if what you're returning is a promise. Until the ES2019 spec, return await somePromise and return somePromise were handled slightly differently, the settlement of the first was delayed one async tick longer than the settlement of the second, but if it's a native promise, a change in the ES2019 spec makes them the same even at that level. (But if somePromise were a non-native thenable, the extra tick would remain.)

Upvotes: 2

Related Questions