0
p1 = new Promise((res,rej)=>{
    console.log("p1 setTimeout");
    setTimeout(()=>{
      res(17);
    }, 10000);
});

p2 = new Promise((res,rej)=>{
    console.log("p2 setTimeout");
    setTimeout(()=>{
      res(36);
    }, 2000);
});

function checkIt() {
    console.log("Started");

    let val1 = this.p1;
    console.log("P1");
    val1.then((data)=>{console.log("P1 => "+data)});

    let val2 = this.p2;
    console.log("P2");
    val2.then((data)=>{console.log("P2 => "+data)});

    console.log("End");
}

checkIt();

My understanding of above written JavaScript code was:

1: In callback queue, p2's setTimeout will be first and then p1's setTimeout (and they will execute in FIFO manner)

2: Callback queue won't execute before microtask queue

3: In microtask queue, p1's callback function will first and then p2's callback function (and they will execute in FIFO manner)

4: Hence this should be deadlock.

But instead getting output:

1: p1 setTimeout

2: p2 setTimeout

3: Started

4: P1

5: P2

6: End

7: (After 2 seconds) P2 => 36

8: (After 10 seconds) P1 => 17

Doubt: How 7th and 8th line of output are coming?

I have ran the code and getting output as defined above

7
  • 1
    I don't understand why you think "deadlock" should happen. But I think you're not understanding the fact that the "callback queue" as you call it here is going to be empty until the setTimeout calls are made, by which point of course the "microtask queue" is empty. Actually even that's not quite right, because setTimeout doesn't put its callback into the "callback queue" until the timeout completes, so there is never more than one item in it at any one point. Commented Mar 31, 2024 at 18:51
  • bro I think, I got wrong. I thought that the very moment when execution reach (val1.then((data)=>{console.log("P1 => "+data)});) it moves the .then() callback function to microtask queue. Is this idea correct? Commented Mar 31, 2024 at 18:55
  • Yes, that's correct. What I think you're missing is that those microtasks (in this case, anyway), only take microseconds to run, and that what they do (call setTimeout) doesn't even add anything to the "callback queue" until the timeout period has passed. Commented Mar 31, 2024 at 19:04
  • @RobinZigmond, erh... that is not correct. Commented Mar 31, 2024 at 19:44
  • @trincot - which part, and why? Happy to correct if I've either made a stupid slip or it turns out my own understanding is wrong! Commented Mar 31, 2024 at 21:34

2 Answers 2

1

@Robin Zigmond (Please once verify this)

I think flow would be like this:

1: p1 setTimeout() will start and after 10 seconds its callback will go to callback queue

2: p2 setTimeout() will start and after 2 seconds its callback will go to callback queue

3: Earlier I though that when execution reaches val1.then((data)=>{console.log("P1 => "+data)}) it moves .then() to microtask queue (I think, this is wrong, because instead .then() of this line, will go to microtask queue when p1 is resolved)

4: Earlier I though that when execution reaches val2.then((data)=>{console.log("P2 => "+data)}) it moves .then() to microtask queue (I think, this is wrong, because instead .then() of this line, will go to microtask queue when p2 is resolved)

5: After 2 seconds, setTimeout() callback will go to callback queue and since there isn't any thing in microtask queue, hence event loop will execute it by moving it to call stack.

6: Since p2 got resolved in line 5, hence its callback function [val2.then((data)=>{console.log("P2 => "+data)})] moves to microtask queue and get executed i.e. P2 => 36 gets printed.

7: After 10 seconds, setTimeout() callback will go to callback queue and since there isn't any thing in microtask queue, hence event loop will execute it by moving it to call stack.

8: Since p1 got resolved in line 7, hence its callback function [val1.then((data)=>{console.log("P1 => "+data)})] moves to microtask queue and get executed i.e. P1 => 17 gets printed.

Sign up to request clarification or add additional context in comments.

1 Comment

Yes, that sounds about right.
0

setTimeout creates a new macrotask queued into the event loop after the timeout, so your promises are queued in different macrotasks and have no relation at all.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.