2

function first() {
  return new Promise(resolve => {
    console.log(2);
    resolve(3);
    console.log(4);
  });
}

async function f() {
  console.log(1);
  let r = await first();
  console.log(r);
  console.log(99);
}

console.log('a');
f();
console.log('b');

In the above code shows the following result:

a
1
2
4
b
3
99

In my understanding, when the compiler hits the await first() function, it pushes the first() function execution to the event queue and pause the execution of f(), continue execution everything after f().So the execution order should be:

a
1
b
2
4
3
99

Apparently, I get it wrong. Can anyone explain to me how this is really working?

Md Monjur Ul Hasan
  • 1,705
  • 1
  • 13
  • 36
  • Possible duplicate of [Resolve order of Promises within Promises](https://stackoverflow.com/questions/42031051/resolve-order-of-promises-within-promises) – OfirD Jun 08 '21 at 17:18

5 Answers5

1

enter image description here

enter image description here

if you didn't understand ,leave a comment . Thank you.

ND NAVEEN
  • 96
  • 5
  • If we using function inside setTimeOut that function will put into wait block but await means the below code should wait for the await function to complete ,so await push all the below code into wait block . – ND NAVEEN Jul 22 '19 at 04:56
  • Thanks for the response. It certainly clear some of the confusions. However, my biggest confusion was the output `b` and the order of 2, 4, b, and 3. Would you elaborate your thought on this. – Md Monjur Ul Hasan Jul 24 '19 at 13:11
1

The await expression causes async function execution to pause until a Promise is settled.once promise is fulfilled or rejected, Then it resumes the execution of the async function.In the mean time it will continue to execute the code out side the async function.

Hemanta
  • 11
  • 1
0

Check this MDN article about Promise's executor parameter.

Executor function is invoked immediately i.e. synchronously.

await is basically waits for a promise resolution/rejection but the synchronous code right after the await statement is executed immediately.

Similarly, take f() invocation, note that you have 1 in console after a immediately although async functions return a promise.

GProst
  • 9,229
  • 3
  • 25
  • 47
0

I think this is actually happening, please see the comments and numbers

function first() {
  return new Promise(resolve => {
    console.log(2); // 5. Print "2"
    resolve(3); // 6. call resolve(3), meaning it will set the resolveCallback state of Promise with 3. 
    console.log(4); // 7. print "4"
  });
}

async function f() {
  console.log(1); // 3. Print "1"
  let r = await first(); // 4. Call the first() method and await the result, control goes to first() 
                        // 8. Since first() method updated the state of resolveCallback, it will assign "3" to variable "r" 
  console.log(r); // 10. print "3" 
  console.log(99); // 11. print "99"
}

console.log('a'); // 1. Start print 'a'
f(); // 2. Since funtion f() is decoreated with async key word it is by default return a promise and control goes to f()
console.log('b'); // 9. Since control release from f() print "b"

Simple terms a Promise allows you to run some code asynchronously and then run other code after it completes and dependent on the result (whether it failed or succeeded).It is created using the constructor pattern.

Signature : function(resolveCallback, rejectCallback)

The constructor returns a Promise object which keeps track of it’s state, and can only be settled once. This means that the resolver and rejector functions together can only receive one call, and the status can’t change from resolved to rejected or vice versa.

Syam
  • 303
  • 1
  • 8
  • This is really a great answer and pinpoints my biggest confusion. However, I am still confused how step 7 in your comments execute right after step 6, as you said in step 6 that the control goes to `f()`. Could you please elaborate on it? – Md Monjur Ul Hasan Jul 24 '19 at 13:13
  • It is because you are using **await** keyword to call first() method. As you may know await keyword makes JavaScript to wait until the **promise returns a result**. Even though we call the resolve() method from the first() method, script will wait for the promise to return. Hope this helps . – Syam Jul 24 '19 at 16:07
  • Thanks for the reply. I think I understand it a bit better now. As per my understanding, at #6, the control does not go to `first()` directly but it does the memory operation r=3 and continues to 7. I also think that it is more logical to merge the explanation of 6 and 8 in 6, and at 7. talk about the control transfer to `console.log('b') and why. Other answers explain that nicely. An answer like that, in my opinion, will help other newbies like me in the future to understand the same problem. And of course, I love to accept that, once modified, as a correct answer :). Thank you very much! – Md Monjur Ul Hasan Jul 24 '19 at 16:35
0

Well, It requires deep understanding of "Task and Microtask execution" in javascript. Every promise is handled through some microtask queue which are run at the end of each task.

As per the documentation, The microtask queue is processed after callbacks as long as no other JavaScript is mid-execution, and at the end of each task. Any additional microtasks queued during microtasks are added to the end of the queue and also processed.

You can find best explanation at https://javascript.info/microtask-queue.

If you are worried about order of execution then use setTimeout within Promise. setTimeout schedules a new task for its callback, so it will run after current task in this scenario

function first() {
  return new Promise(resolve => { setTimeout(()=>{
    console.log(2);
    resolve(3);
    console.log(4);
  }); });
}

async function f() {
  console.log(1);
  let r = await first();
  console.log(r);
  console.log(99);
}

console.log('a');
f();
console.log('b');

CoronaVirus
  • 401
  • 2
  • 7
  • 20