4

Do all functions in an async/await chain have to use the async/await keyword?

async function one() {
  return await fetch(.....);
}

async function two() {
  return await one();
}

async function three() {
  return await two();
}

I've seen some examples in tutorials where the caller doesn't have to use the keyword.

GN.
  • 8,672
  • 10
  • 61
  • 126
  • 2
    Only if you depend on the value return. Asynchronous execution has to be turtles all the way down. If you don't care if the dependent function has finished, you don't have to `await` it. Additionally, you don't have do `return await fetch`, just do `return fetch`. – zero298 Mar 19 '19 at 21:39
  • 1
    Actually, is your question, "do I need to `await` before returning", or is it, "do I always need to `await` everything?". I can't tell. – zero298 Mar 19 '19 at 21:41
  • Answer to OP: no, your function can return directly a Promise without being async. It will still awaitable. Async basically wraps your function into promise (more or less, this is not precise), whereas await unwraps that promise within an async context. So everywhere you'd expect async function, you can pass Promise instead. – netchkin Mar 19 '19 at 21:42
  • [Don't use `return await`](https://stackoverflow.com/a/43985067/1048572) – Bergi Mar 19 '19 at 21:45
  • 1
    No, a function doesn't need to be `async` to be `await`able. It just needs to return a promise. – Bergi Mar 19 '19 at 21:46
  • @Bergi - await can be applied to primitive values, similar to the way `Promise.all` accepts primitive values its argument array. Although not necessarily useful, you can await a function call without knowing if it returns a promise or not. – traktor Mar 19 '19 at 22:16
  • @traktor53 Of course, I was only considering the useful and interesting case. – Bergi Mar 19 '19 at 22:27

1 Answers1

6

No, at least not for this example - if you have a function that is just awaiting a Promise and returning the result, you can just return that Promise alone, without any async or await:

function one() {
  return fetch(.....);
}

function two() {
  return one();
}

function three() {
  return two();
}

If you want to have a flat function body, you would need to use await when that function consumes a Promise and needs to do something else before returning another resolved Promise to the caller. For example:

async function one() {
  const fetchResult = await fetch(.....);
  // do something with fetchResult
  return foo;
}

function two() {
  return one();
}

function three() {
  return two();
}

Here, one is awaiting the fetch call, and doing something with it afterwards before returning a Promise, but two and three don't need to be async because, again, they're just calling a function that returns a Promise and returning that Promise to the caller. If two or three also had to do something after waiting but before resolving, then they would have to use await (if you wanted a flat function body):

async function one() {
  const fetchResult = await fetch(.....);
  // do something with fetchResult
  return foo;
}

async function two() {
  const oneResult = await one();
  console.log('got result for one');
  return oneResult;
}

function three() {
  return two();
}
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • If `one` does something with the fetch result, and returns a value (not a promise, say some JSON), does `two` have to use `await` when calling it? – GN. Mar 20 '19 at 22:32
  • If `two` needs to do something other than return it immediately, then yes - this is because all `async` functions return Promises regardless. So, if you're in a function, in order to consume the Promise, get the JSON out of it, and parse that JSON into an object, you would have to `await` the call of the `async` function. – CertainPerformance Mar 20 '19 at 22:46
  • 1
    Pretty much all functions *will* do something with a Promise they consume before returning it, so with regard to your original question, *most* of the time, in this sort of situation, everything in the asynchronous chain will be `await`ing the Promise of the next `async` function. – CertainPerformance Mar 20 '19 at 22:47