1

I created 3 promise, p1, p3 resolve while p2 rejects.

code:

            let p1 = new Promise((resolve, reject) => {
                resolve(42);
            });
            let p2 = Promise.reject(43);

            let p3 = new Promise((resolve, reject) => {
                resolve(44);
            });
            let p4 = Promise.race([p1, p2, p3]);

            p4.catch((value) => {
                console.log(value); 
            });

Base on code, p4 is supposed to return 43, because p3 runs faster than p1 and p2. When I run in node, it returns none. How to explain this situation in Promise.race?

Note: Please run this code in console then answer it. It doesn't return anything in my local.

  • Possible duplicate of [What is the order of execution in javascript promises](https://stackoverflow.com/questions/36870467/what-is-the-order-of-execution-in-javascript-promises) – ibrahim tanyalcin May 04 '18 at 00:07
  • @ibowankenobi , I just read that post, there is no code for Promise.race – landscape1250 May 04 '18 at 00:12
  • 2
    The order cannot be relied. You cannot say, p3 or even p1 will run faster than the other. You have 4 expressions evaluated at the same tick of event loop, there is a separate microtask queue for promises and you cannot say which one will run faster. – ibrahim tanyalcin May 04 '18 at 00:17
  • Np, good luck with your project. – ibrahim tanyalcin May 04 '18 at 01:05
  • By now you probably figured out that you're passing resolved or rejected promises and `Promise.race` will return the first resolved or rejected it finds so `let p4 = Promise.race([p2,p1, p3]);` will log something in `catch`. If you need a function that will return first promise that resolves or rejects if all promises reject you can try [this](https://github.com/amsterdamharu/lib/blob/master/src/index.js#L368-L416) – HMR May 04 '18 at 04:26

1 Answers1

2

As you've written them in your example, thee promises p1, p2, and p3 all settle at the same time*.

From the docs of Promise.race:

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

While those promises aren't already settled when given to race, since they all settle at the same time, race will use the result of the first one in the list. In this case, that's p1.

So:

p4.then(console.log) // Prints 42

and you can verify that by noting that if you change the order of p1, p2, and p3 in the array you give to race, you'll always see the result of the first one.

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

let p2 = Promise.reject(43);

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

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

p4.then(r => console.log("p4", r), r => console.log("p4", r));
p5.then(r => console.log("p5", r), r => console.log("p5", r));
p6.then(r => console.log("p6", r), r => console.log("p6", r));
CRice
  • 29,968
  • 4
  • 57
  • 70
  • Hi, the truth is it return nothing, you can run it in terminal. It cannot return anything. – landscape1250 May 04 '18 at 00:33
  • I'm not sure what you mean by *"it cannot return anything"*. If you mean you don't see any logs, it's because your `p4.catch( ... )` code will never execute since the promise does not reject, but resolves with `42`. – CRice May 04 '18 at 00:38
  • I see, p2 is already rejected so p4's result is ignored, so console.log(value) in p4 returns nothing, right? – landscape1250 May 04 '18 at 00:43
  • no p4's "result" is a promise that resolves to 42 - your `console.log` only executes if p4 rejects – Jaromanda X May 04 '18 at 00:52