The Promise object is a new addition to ECMAScript 6 that normalizes asynchronous processing objects and processing rules in JavaScript. Promise.any(), Promise.All (), promise.AllSettled (), and Promise.AllSettled (). Promise. Race ([P1, p2, p3]) promises. The Promise array in the Promise. Output only the fastest promise, regardless of whether the result itself is a successful fulfillment state or a failed rejection state.

Here’s how promise.race () works.

1. Working principle

Promise.race() returns a Promise that is fulfilled or rejected once one of the promises in the iterator is fulfilled or rejected.

The function takes an array of Promises (or usually an iterable) as an argument, like this:

const racePromise = Promise.race(promises);
Copy the code

When a promise is quickly fulfilled or rejected among all entered promises, racePromise will parse the fast-fulfilled promise (fulfilled or rejected) :

The results of a racePromise can be extracted using the then method:

Racepromise.then ((fastValue) => {fastValue // fast complete promise});Copy the code

Async /await syntax can also be used:

const fastPromise = await racePromise;

fastPromise; //  快速完成的 promise
Copy the code

Promise.race() returns the same Promise information as the Promise that was completed first.

Promise.race() differs from promise.any () : promise.race () looks for the first Promise to fulfill or reject in the Promise list; Promise.any() looks up the first fulfilled Promise from the list of promises.

2. Usage Guide

Before we dive into the use of promise.race (), let’s also define two simple functions.

function resolveTimeout(value, delay) {
    return new Promise((resolve) => setTimeout(() => resolve(value), delay));
}
function rejectTimeout(reason, delay) {
    return new Promise((r, reject) => setTimeout(() => reject(reason), delay));
}
Copy the code

Next, try promise.race () using the two helper functions defined above.

2.1 Complete allpromises

We define an array of promises called racePromises, all of which have a successful resolve value as follows:

const fruits = ["potatoes", "tomatoes"]; const vegetables = ["oranges", "apples"]; const racePromise = Promise.race([ resolveTimeout(fruits, 5000), resolveTimeout(vegetables, 1000), ]); // Wait 1 second... const list = async () => { try { const fastPromise = await racePromise; console.log(fastPromise); } catch (error) { console.log(error); }}; list(); // [ 'oranges', 'apples' ]Copy the code

From the results of the above execution, promise.race () returns the resolve result of the fastest fulfilled Promise.

2.2 apromiserejected

Return the first promise (rejected);

const fruits = ["potatoes", "tomatoes"]; const racePromise = Promise.race([ resolveTimeout(fruits, 2000), rejectTimeout(new Error("Vegetables is empty"), 1000), ]); // Wait 1 second... const list = async () => { try { const fastPromise = await racePromise; console.log(fastPromise); } catch (error) { console.log(error); }}; list(); // Error: Vegetables is emptyCopy the code

According to the result, the first fulfilled promise is rejected. The fastPromise return promise is also rejected.

The commitment time of Rejected is extended to 5 seconds as follows:

const fruits = ["potatoes", "tomatoes"]; const racePromise = Promise.race([ resolveTimeout(fruits, 2000), rejectTimeout(new Error("Vegetables is empty"), 5000), ]); // Wait 2 seconds... const list = async () => { try { const fastPromise = await racePromise; console.log(fastPromise); } catch (error) { console.log(error); }}; list(); // [ 'potatoes', 'tomatoes' ]Copy the code

As you can see from the execution result above, the promise returned by fastPromise fulfills resolve if the promise that completed fastest fulfills resolve.

2.3 allpromisesrejected

All promises above are rejected, the code is as follows:

const racePromise = Promise.race([ rejectTimeout(new Error("Fruits is empty"), 2000), rejectTimeout(new Error("Vegetables is empty"), 1000), ]); // Wait 1 second... const list = async () => { try { const fastPromise = await racePromise; console.log(fastPromise); } catch (error) { console.log(error); }}; list(); // Error: Vegetables is emptyCopy the code

As a result, although both promises were rejected, fastPromise returned promises were rejected the fastest.

3. Application scenarios

3.1. Performance test

Promises can be used to test performance optimization for network or database requests on projects with asynchronous operations, by using promise.race () to test the response time of two different approaches.

3.2 Best Choice

For example, there are multiple request servers to obtain the same type of data and send requests to multiple servers at the same time. As long as one of them completes the work, its data will be presented to achieve the effect of selecting the best line. This is possible using promise.race () to simultaneously execute the Promise and complete immediately after the first success.

conclusion

The article introduces the principle and use of promise.race (), and adds two possible scenarios. The basic difference between promise.race () and promise.any () is that Promise.race() performs callbacks for the first resolved and rejected promises, while promise.any () performs callbacks for the first fulfilled promises, A special attribute AggregateError is rejected if no promise is fulfilled.