Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript ES6 - Possible race condition between promise resolution and event?

Is it possible to have user code executed between a promise resolution and a promise await return?

function a () {
  return new Promise(resolve => {
    setTimeout(() => {
      // Between here...
      resolve()
    }, 1000))
  }
}

async function b () {
  await a()
  // ...and here ?
}

Does the specification enforces that Promise callbacks are called immediatly? I wonder if an event could be handled by the virtual machine between the 2 points, possibly causing side-effects.

like image 451
Yovar Avatar asked Jul 25 '17 09:07

Yovar


People also ask

What happens if one of the promises in promise race rejects with an error?

race you tell the system that you only care about the first promise that is either rejected or resolved, the second one is ignored.

Does promise race cancel promise?

race() The Promise. race() method returns a promise that fulfills or rejects as soon as one of the promises in an iterable fulfills or rejects, with the value or reason from that promise.

What is difference between promise all and promise race?

The Promise. all() returns a promise that resolves to an array of values from the input promises while the Promise. race() returns a promise that resolves to the value from the first settled promise.

Does promise wait for resolve?

You can use the async/await syntax or call the . then() method on a promise to wait for it to resolve. Inside of functions marked with the async keyword, you can use await to wait for the promises to resolve before continuing to the next line of the function.


2 Answers

No, it doesn't enforce immediate calling. The spec runs through a number of steps upon resolving a promise, one of which is:

  1. Perform EnqueueJob ("PromiseJobs", PromiseResolveThenableJob, «‍promise, resolution, thenAction»)

Note that depending on the state of the promise, different routes can be taken. However, they all end at EnqueueJob, which says:

  1. Add pending at the back of the Job Queue named by queueName.

So any further executions are deferred to the end of the job queue.

like image 127
James Thorpe Avatar answered Oct 21 '22 09:10

James Thorpe


Promise callbacks are not called immediately. Your function b() transforms to

function b () {
  return a().then(() => {
    // Do something
  });
}

where the function which is given to then is executed at some point of time by the eventloop after the promise from a was resolved. It will never be called synchronously, because the specification guarantees that Promise continuations always run with an empty call stack (which means in a fresh iteration of the eventloop). Therefore some other code (e.g. from another promise resolval) can run between the time where the promise was resolved and when the continuation runs.

like image 30
Matthias247 Avatar answered Oct 21 '22 08:10

Matthias247