Sebastian
Sebastian

Reputation: 1305

The order of executing and resolving promises from a job queue with Promise.race

I'm trying to wrap my brain around the job queue and resolving promises in Javascript. I use the book of Nicholas Zakas "Understanding ECMAScript 6", and there is this fragment of code about Promice.race() with description, which I bolded, that i don't understand:

let p1 = new Promise(function(resolve, reject) {
    resolve(42);
});

let p2 = Promise.reject(43);

let p3 = new Promise(function(resolve, reject) {
    resolve(44);
});

let p4 = Promise.race([p1, p2, p3]);

p4.catch(function(value) {
    console.log(value);     // 43
});

Here, p4 is rejected because p2 is already in the rejected state when Promise.race() is called. Even though p1 and p3 are fulfilled, those results are ignored because they occur after p2 is rejected.

I know that Promise.race() settles as soon as first of all promises provided is settled. But why does the book claim promise p1 settles after p2? If the code goes from the top to the bottom, the p1 occurs first, so I assume it should settle first. Is it because of the wrapping in function? Or javascript executing order that I don't understand?

Could someone clarify that concept for me?

Upvotes: 2

Views: 360

Answers (2)

Dennis Cual
Dennis Cual

Reputation: 99

I agree of Bergi's answer. A promise constructor callback is invoked synchronously in case you need to access the resolve/reject function outside the scope of constructor. According to your code snippet, it's indeed called synchronously. But if the resolve/reject function is executed through ajax request, or wrap to a setTimeout function, the process would be asynchronous.

const p1 = new Promise((resolve, reject) => {
   setTimeout(() => resolve(42), 100); // this will result in asynchronous process.
});

Upvotes: 0

Bergi
Bergi

Reputation: 664538

The book appears to be wrong on that account. Indeed, p1 is fulfilled before p2 is even constructed, and when executing the example you get the result "42" not the rejection "43".

The author might have been confused about the new Promise callback actually is invoked synchronously, unlike all other promise callbacks (that go through then). Maybe the example was meant to be

let p1 = Promise.resolve().then(() => 42);
//                              ^^^^^^^^ asynchronous
let p2 = Promise.reject(43);
let p3 = Promise.resolve(44);

let p4 = Promise.race([
  p1, // still pending
  p2, // already rejected
  p3  // already fulfilled
]); // so p4 will get rejected, as its callback on p2 is the first to be invoked in order
p4.then(console.log, console.error);

Upvotes: 3

Related Questions