0

const p1 = new Promise((resolve,reject) => {
  setTimeout(()=>{
    resolve("xxx");
  }, 5000)
});

const p2 = new Promise((resolve,reject) => {
  setTimeout(()=>{
    resolve("xx");
  }, 10000)
});


async function he() {
  console.log("start"); 

  const s1 = await p1;
  console.log("Rome");

  const s2 = await p2;
  console.log("Paris");
}

he();
console.log("Hey bro")

Question - Now when program execution starts, it prints "start" and then "hey bro" instantly and JS does not wait the await to finish and continue with the execution. Now when JS encounters p1 in he(), it prints "Rome" after 5 sec , and then after next 5 sec, it prints Paris.

Now my question is, why didn't it print Paris after 10 sec? How did the timer start of p2 even before it reached p2 initialization? or did it? I know that when it encounters p1 it halts the execution of he() func in callstack, is this the time where it starts executing s2 behind the scenes somehow?

10
  • 1
    Now my question is, why didn't it print Paris after 10 sec? for the same reason you see hey bro straight after start - the async calls are not blocking, so the next function invocation occurs immediately. Commented Nov 9, 2023 at 14:26
  • but from what I have learnt, maybe as soon as the program encounters a promise with await, it removes that function from callstack! So, that is why, when p1 was encountered, it printed "hey bro" immediately, but if what I have learnt is correct, then how did execution of p2 started even before it finished with p1? becz the func itself was not in the callstack Commented Nov 9, 2023 at 14:28
  • 2
    Because you started both timers simultaneously. If you want to start the 2nd timer after the 1st replace const p1 = new Promise(... with const p1 = () => new Promise(... (same with p2) and replace await p1 with await p1() Commented Nov 9, 2023 at 14:29
  • 4
    Note that the callback to new Promise() is not delayed. It is executed synchronously (not asynchronously). So you created p2 too early Commented Nov 9, 2023 at 14:30
  • 2
    You are obsessing at the wrong place. Yes, js execute line by line. That's why const p1 = new Promise() is exectued before const p2 = new Promise(). You're too obsessed with the await p1 which is not where the setTimeout() is created. You are looking at the wrong place. Commented Nov 9, 2023 at 14:33

2 Answers 2

1

How did the timer start of p2 even before it reached p2 initialization?

It didn't start when you did this:

const s2 = await p2;

It started when you did this:

const p2 = new Promise((resolve,reject) => {
  setTimeout(()=>{
    resolve("xx");
  }, 10000)
});

That is, both timers/promises started immediately. All you're doing in the he function is awaiting the results of those promises, but they've already started.

The first timer was 5 seconds, the second was 10 seconds. They start at the same time and run simultaneously.

You could achieve the result you're looking for by not defining the promises until you want to await them. For example:

async function he() {
  console.log("start"); 

  const s1 = await new Promise((resolve,reject) => {
    setTimeout(()=>{
      resolve("xxx");
    }, 5000)
  });
  console.log("Rome");

  const s2 = await new Promise((resolve,reject) => {
    setTimeout(()=>{
      resolve("xx");
    }, 10000)
  });;
  console.log("Paris");
}

he();
console.log("Hey bro")

Or by defining functions which create/return the promises instead of defining the promises themselves:

const p1 = () => new Promise((resolve,reject) => {
  setTimeout(()=>{
    resolve("xxx");
  }, 5000)
});

const p2 = () => new Promise((resolve,reject) => {
  setTimeout(()=>{
    resolve("xx");
  }, 10000)
});


async function he() {
  console.log("start"); 

  const s1 = await p1();
  console.log("Rome");

  const s2 = await p2();
  console.log("Paris");
}

he();
console.log("Hey bro")

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

Comments

0

Because it is asynchronous, and you're not awaiting he(). You can't await at the top level, but if you nest the whole program in an async function you can await he() and see it behave as I believe you are expecting.

const p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("xxx");
  }, 5000)
});

const p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("xx");
  }, 10000)
});


async function he() {
  console.log("start");

  const s1 = await p1;
  console.log("Rome");

  const s2 = await p2;
  console.log("Paris");
}


async function runProgram() {
  await he();
  console.log("Hey bro")
}

runProgram();

Furthermore, it is worth noting that you are not calling p1 and p2- they are promises that start counting down the moment you assign them, so even if you didn't call he(), they would resolve at 5 and 10 seconds after they were initialized and assigned.

2 Comments

could you pls answer me this? "but from what I have learnt, maybe as soon as the program encounters a promise with await, it removes that function from callstack! So, that is why, when p1 was encountered, it printed "hey bro" immediately, but if what I have learnt is correct, then how did execution of p2 started even before it finished with p1? becz the func itself was not in the callstack"
@Rocko I'm not sure I entirely understand your question, but it seems like you're confused about how execution continues after starting the first timeout. I think you're confused on two fronts: 1) You're not actually calling p1 and p2 - you start their timers the moment you define them because that's how you wrote it, and 2) Although JS may not be multithreaded it is still capable of async execution, and the entire purpose of things like setTimeout is to allow execution to continue unfettered while you wait to execute what is passed to setTimeout (unless you await).

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.