2

lets consider we have N async functions like:

async function1(){
  return await fetch(...);
}
.
.
.
async functionN(){
  return await fetch(...);
}

then we have a function like:

async wrapper(){
   let var = await fetch(...);
   function1();
   .
   .
   .
   functionN();
}

would this create one big microtask queue that would effectively block ui thread going to next task before all called functions resolved their awaits?

Kamil Naja
  • 6,267
  • 6
  • 33
  • 47
dee zg
  • 13,793
  • 10
  • 42
  • 82
  • I don't get what you mean by "nesting" here. Is it on purpose that you are not `await`ing the `functionN()` calls? – Bergi Feb 20 '19 at 20:54
  • There is only one microtask queue, and it exists in the runtime, outside of your code. It does not get "created". – Bergi Feb 20 '19 at 20:55
  • yes, its on purpose. a kind of fire and forget...but i am actually questioning is it a real forget or remembering it on a huge microtask queue and blocked ui? – dee zg Feb 20 '19 at 20:56
  • [Measure it](https://ericlippert.com/2012/12/17/performance-rant/). – Heretic Monkey Feb 20 '19 at 20:58
  • @Bergi i am aware its only one microtask queue outside of my code:). correct phrasing would be: would the code above create a lot of microtasks in microtask queue scheduled for execution before new task? – dee zg Feb 20 '19 at 21:00
  • Nothing is scheduled on the queue until any of the promises are settled. – Bergi Feb 20 '19 at 21:03
  • Btw, [don't use `return await`](https://stackoverflow.com/q/43353087/1048572) – Bergi Feb 20 '19 at 21:04

1 Answers1

4

There is nothing in the microtask queue until promises resolve. Until then other tasks and (UI) events can be processed.

This is because the await operator will make the corresponding async function return immediately, allowing other JS code to execute. In your case the promise is returned by fetch, which in practice will not resolve immediately. So there is nothing blocking here.

Then when the HTTP response makes the fetch promise resolve, a microtask will indeed be created, which, when when executed will restore the corresponding async function's execution context. Your example function has nothing else to do, so that is quickly done.

Note that it does not matter whether this function was originally called from within some other function: at this stage, only that particular function's execution context (in which an awaited promise resolved) is restored without any pre-existing callstack. So it does not return again to the wrapping function. That already happened in the first phase and will not happen again.

Then again there is free event processing until the next fetch promise resolves. And so it continues.

trincot
  • 317,000
  • 35
  • 244
  • 286