0

Here's the code:

function B() {
  return 'B';
}

async function test(b) {
  await console.log('Z')
  await console.log(b())
  console.log('X')
  await console.log("hihihi")
}

console.log('A');
test(B);
console.log('C');
console.log('P');

This output's to A Z C P B X hihihi

Question is:

  • Why does the control goes to the caller function(that called the async function) after executing the first await statement? How's it useful?
  • What's to be done to force execute all await statements one after the other somehow preventing it from going to the caller function?
Aditya Patnaik
  • 1,490
  • 17
  • 27

2 Answers2

2

Right now, your single node thread sees an order of execution that looks like this

console.log('A') // > A
test(B) // oh okay, looks like an async function call. i'll start this off and move on
console.log('C'); // > C
console.log('P'); // > P

When test(B) is called, another "thread" of sorts handles the execution. This is all because test is an async function, so every operation inside that function is handled a bit differently than a regular synchronous function.

If you want them all to appear in order, you can use another async function and await test(B)

function B(){
  return 'B';
}

async function test(b){
  await console.log('Z')
  await console.log(b())
  console.log('X')
  await console.log("hihihi")
}

async function main() {
  console.log('A');
  await test(B);
  console.log('C');
  console.log('P');
}

main()

All of this is pretty useful because of a nodejs thing called non-blocking io. Here's a question that could shed some light on that.

Here is node's very own explanation of the event loop, which is a key concept for understanding non-blocking io

richytong
  • 2,387
  • 1
  • 10
  • 21
  • Thanks for such an insightful answer @richytong, does that mean each async function runs over a new thread? – Aditya Patnaik May 30 '20 at 19:27
  • 1
    I put the quotes around "thread" because you can sorta think about it like a thread, but it's not a separate thread in the conventional sense. This [blog post](https://blog.logrocket.com/node-js-multithreading-what-are-worker-threads-and-why-do-they-matter-48ab102f8b10/) can shed more light – richytong May 30 '20 at 19:28
  • So the nodejs just invokes the async function and waits for the result. Meanwhile, it does not block the execution of other pieces of syncronous code while waiting for a response from the async func. Correct? – Aditya Patnaik May 30 '20 at 19:37
  • 1
    Thanks so much @richytong – Aditya Patnaik May 30 '20 at 20:42
1

When a promise is done, any further execution is going into a queue there is executed after the code there is running at the moment,

first, console.log('A') is called as normal

then console.log('Z') is called as normal, but javascript is exception a promise, but it is fine for it to take a normal statement, but any code after the call stack is been emptying

then c and p is logged

now the callstack is empty, and now its time for evaluating the microtask queue

b is called. and another microtask is carried out

x is logged normal

hi hi hi is logged, and another microtask is started, but then the function exits

I really do recommend watching "the event loop" which goes into details with this functionality https://www.youtube.com/watch?v=cCOL7MC4Pl0 done by Jake which also have an article on it https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/

everthing is called on the same thread, see richytong's code block for your 2nd question

Benjaco
  • 303
  • 3
  • 11
  • that video was really helpful! However now i have a few questions. I understood that there is a JSStack and a Microtask Stack, every process gets into the JSStack for the execution and all subprocesses in that task go into Microtasks Stack and they wait for the current Task(in JS Stack) to get all the sync code executed, So that the waiting microtasks can get into the JSStack for execution. So in this question, does all the await statements and the B() function gets into the microtask Stack assuming the async function gets into the JSStack? – Aditya Patnaik May 30 '20 at 20:20
  • 1
    Yes, you can say that you first push "await console.log(b()); console.log('X'); await console.log("hihihi")" into the microtask stack, then pushes "console.log('X'); await console.log("hihihi")" into the stack after the first await statement in block – Benjaco May 30 '20 at 20:40