At the 71st Ecma TC39 rally, the project and reference implementation of Promise.allSettled
, the third of four major promise combinators, will be considered.
Authors : Jason Williams (BBC), Robert Pamley (Bloomberg), Mathias Beinens (Google)
Champion : Mathias Beinens (Google)
Stage : 3
For fans of podcasts, duplicated on YouTube .
There are four main combinators in the world of promises:
Promise.all
. ES2015. Closes on the first rejected promise.Promise.race
. ES2015. Closes the ground at least somehow resolved / settled promise.Promise.any
. Stage 1. Closes at the first satisfied promise.Promise.allSettled
. Stage 3 → Stage 4. Does not close.All of them are widely represented in regular user libraries, each of them is useful in itself and is suitable in different situations.
The main use of this combinator comes when you want to perform an action immediately after the completion of multiple requests, regardless of whether they ended in success or failure. The remaining promise combinators close ( short-circuit ), discarding the results of incoming values that lost in the race after a certain system state. Promise.allSettled
is unique in that it always expects everyone for whom it is responsible.
Promise.allSettled
returns a promise, which is performed with the return of an array of snapshots of promise states, but only after all the original promises are resolved (settled).
We say that the promise is settled , if it is not suspended pending , i.e. when he is either satisfied or rejected - one of two things. To understand the terminology, take a look at the old States and Fates document.
And yet, this name, allSettled
, is widely used in existing libraries that implement this functionality. The list will be below.
Imagine you need to iterate over an array of promises and return a new value with a known status (which occurs in any of two possible branches of logic).
function reflect(promise) { return promise.then( (v) => { return { status: 'fulfilled', value: v }; }, (error) => { return { status: 'rejected', reason: error }; } ); } const promises = [ fetch('index.html'), fetch('https://does-not-exist/') ]; const results = await Promise.all(promises.map(reflect)); const successfulPromises = results.filter(p => p.status === 'fulfilled');
The proposed API allows the developer to process these options, without the need to create a function to reflect
independently, or to store the results in temporary variables. The new API looks like this:
const promises = [ fetch('index.html'), fetch('https://does-not-exist/') ]; const results = await Promise.allSettled(promises); const successfulPromises = results.filter(p => p.status === 'fulfilled');
If for some reason we need rejected promises, then we probably need to collect the reasons for what happened. allSettled
makes it just as easy to do this.
const promises = [ fetch('index.html'), fetch('https://does-not-exist/') ]; const results = await Promise.allSettled(promises); const errors = results .filter(p => p.status === 'rejected') .map(p => p.reason);
Quite common is the desire to know that all requests have been completed, regardless of the state of each of them. This is important when you want in the future to do a gradual improvement. We do not always need to get a response from the API.
const urls = [ /* ... */ ]; const requests = urls.map(x => fetch(x)); // , - , - - . // , . try { await Promise.all(requests); console.log(' , .'); } catch { console.log('- , . .'); }
Using Promise.allSettled
you can write something that more closely matches our expectations.
// , API . Promise.allSettled(requests).finally(() => { console.log(' : , '); removeLoadingIndicator(); });
Similar functionality exists in other languages, under different names. Since there is no universal mechanism that is compatible with many languages at once, this document follows the names of the libraries listed above. Here’s how it looks in other languages:
futures::join
;Task.WhenAll
. You can use either try / catch or TaskContinuationOptions.OnlyOnFaulted
;asyncio.wait
with the ALL_COMPLETED
optionCompletableFuture.allOf
Source: https://habr.com/ru/post/459970/
All Articles