1

Why does this behavior happen with Promise.race(), that Promise.resolve(1) calculates faster rather than just 2?

Promise.race([Promise.resolve(1), 2]).then(console.log)
Mina
  • 14,386
  • 3
  • 13
  • 26
  • 1
    Because you're racing an already-settled promise and a value, so you just get whichever's first. – jonrsharpe Sep 10 '22 at 08:09
  • @jonrsharpe eh, this is a byproduct of the spec rather than an intentional design decision. It was very close to a different design where the 2 would win the race at several points in the spec process. I do agree the current design is probably better but I also agree with OP that it's not-obvious. – Benjamin Gruenbaum Sep 10 '22 at 08:12

2 Answers2

1

From MDN docs

If the iterable contains one or more non-promise value and/or an already settled promise, then Promise.race will settle to the first of these values found in the array

const foreverPendingPromise = Promise.race([]);
const alreadyFulfilledProm = Promise.resolve(100);

const arr = [foreverPendingPromise, alreadyFulfilledProm, "non-Promise value"];
const arr2 = [foreverPendingPromise, "non-Promise value", Promise.resolve(100)];
const p = Promise.race(arr);
const p2 = Promise.race(arr2);

console.log(p);
console.log(p2);
setTimeout(() => {
  console.log("the stack is now empty");
  console.log(p);
  console.log(p2);
});

// logs, in order:
// Promise { <state>: "pending" }
// Promise { <state>: "pending" }
// the stack is now empty
// Promise { <state>: "fulfilled", <value>: 100 }
// Promise { <state>: "fulfilled", <value>: "non-Promise value" }
Konrad
  • 21,590
  • 4
  • 28
  • 64
1

Basically, Promise.race and Promise.all implicitly call Promise.resolve on arguments and the 1 just comes before the 2.

This is also true for the values returned from then callbacks, things you await and several other places and the idea was to make it easier to inter-op between promise and non-promise code.

Benjamin Gruenbaum
  • 270,886
  • 87
  • 504
  • 504