📜 ⬆️ ⬇️

Promise.allSettled


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 .


Introduction and Motivation


There are four main combinators in the world of promises:



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).


Where did the name allSettled come from?


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.


Examples


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); 

Real examples


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(); }); 

Custom implementations



In other languages


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:



Materials for further study



Minutes from TC39 meetings



Specification



Implementations



')

Source: https://habr.com/ru/post/459970/


All Articles