skip to Main Content

I’m a beginner. Got confused about async programming after seeing the output of this code

async function f1() {
   console.log('this is f1');
  let res = await f3();
  console.log('result of f1 from f3 = ', res['status']);
  console.log('end of f1');
}

async function f3() {
  console.log('this is f3') 
  console.log('returning res from f3');
  return {"status": 600} ;
}

f1();
console.log('inside global context');

Now my doubt is even though there is no async work going on in f3() as everthing is console logs and a simple return, why don’t the output returned by f3 gets printed immediately in f1(), rather first the inside global context gets printed and then the console logs of f1() gets printed. What exactly did f3 return (I assume a resolved promise) and why didn’t f1 immediately used it ?
If I’m not wrong f1 is still inside call stack when f3 returns a json

2

Answers


  1. What exactly did f3 return (I assume a resolved promise)

    Yes, that’s correct.

    why didn’t f1 immediately used it ?

    Because of the await. Promises are deliberately designed so that if you await one (or call .then), the resuming of code always happens asynchronously. This means that as a developer you can be confident that the order of execution will be the same whether the promise is already resolved, or if some time must pass before it resolves. If this wasn’t the case, it could result in some difficult bugs.

    More specifically, resuming after a promise is achieved by queuing up a "microtask". That means that once all synchronous code has finished running, javascript will immediately run the code in the microtask. Nothing happens in between the end of normal code and the start of a microtask (eg, no browser paint, no setTimeout’s going off).

    If you’d like to know more about microtasks and the event loop, this talk is an excellent one about how javascript schedules everything: https://www.youtube.com/watch?v=cCOL7MC4Pl0

    Login or Signup to reply.
  2. If I’m not wrong f1 is still inside call stack when f3 returns a json

    The thing is that f3 does not return that, but a promise (as f3 is an async function). That promise is resolved with the object {"status": 600}. Yes, f1 is still on the call stack when that promise is returned.

    NB: please don’t call that a "json". It is a JavaScript object. JSON is a text representation and would have a string data type.

    An important realisation is that when an async function (like f1) executes an await, it evaluates the operand and then returns! Its execution context is saved so that it can be resumed later, but it first returns, and it returns a promise.

    Once the call stack becomes empty, the microtask queue will be processed, and that is where the job is that will restore the execution context of f1 that was saved, and so only then f1 will resume execution below the await expression.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search