Learnitweb

Understanding Promise.race() in JavaScript

The Core Idea of Promise.race()

Promise.race():

  • Takes an array of promises
  • Returns a single promise
  • Resolves or rejects as soon as the first promise settles
  • Ignores the rest afterward

This means:

  • The result depends entirely on which promise finishes first.
  • The first resolved OR rejected promise wins.

Real-Life Example: Borrowing a Pen at School

Let’s understand this with a simple real-world example.

Imagine:

  • You forgot your pen at home.
  • You ask three friends for help:
    • John
    • Eugene
    • Susie

Each one replies at a different speed.

Their response times:

FriendResponse TimeHas a Pen?
John3 secondsYes
Eugene5 secondsNo
Susie2 secondsYes

You don’t want to wait for everyone — you just want the first available pen.

Once someone responds positively, you stop waiting.

This is exactly how Promise.race() behaves.

Modeling This in JavaScript

Each friend is represented by a function that returns a promise.

function askJohn() {
    return new Promise(resolve => {
        setTimeout(() => resolve("John: I have a pen"), 3000);
    });
}

function askEugene() {
    return new Promise((resolve, reject) => {
        setTimeout(() => reject("Eugene: Sorry, I don’t have one"), 5000);
    });
}

function askSusie() {
    return new Promise(resolve => {
        setTimeout(() => resolve("Susie: I have a pen"), 2000);
    });
}

Using Promise.race()

Now let’s run all of them in parallel:

Promise.race([
    askJohn(),
    askEugene(),
    askSusie()
]).then(result => {
    console.log(result);
});

Output after 2 seconds:

Susie: I have a pen

Why?

Because Susie responded the fastest.

Important Behavior of Promise.race()

Promise.race():

  • Resolves as soon as the first promise resolves
  • Rejects as soon as the first promise rejects
  • Does not wait for the rest

What If the Fastest Response Is a Rejection?

Let’s change Eugene’s response time so that he replies first, but with a rejection.

function askEugene() {
    return new Promise((resolve, reject) => {
        setTimeout(() => reject("Sorry, I only have one pen"), 1000);
    });
}

Now let’s run:

Promise.race([
    askJohn(),
    askEugene(),
    askSusie()
])
.then(result => console.log(result))
.catch(error => console.log(error));

Output:

Sorry, I only have one pen

Explanation:

  • Eugene responds first
  • His response is a rejection
  • Promise.race() immediately rejects
  • Other promises are ignored

Using Already Resolved Promises

If one of the promises is already resolved, it wins immediately.

Example:

function askShop() {
    return Promise.resolve("We always have pens. Buy one for $1.");
}

Now let’s include it:

Promise.race([
    askJohn(),
    askEugene(),
    askSusie(),
    askShop()
]).then(result => {
    console.log(result);
});

Output:

We always have pens. Buy one for $1.

Even though askShop() appears last in the array, it wins because it resolves immediately.