A Short introduction on Promise.any

Description

Promise.any takes an unspecified number of promises that need to be executed. It returns a promise that is fulfilled by the first promise to resolve successfully and the resulting value is passed back.

If all of them fail, Promise.any throws an exception and executes the reject portion of the promise with a list of all the exceptions.

Project.race can do this right?

Project.race operates similarly, but there is one main difference. If any of the passed in promises return an error, Project.race will reject, regardless of the state of other promises. A resolved promise, even if it executes first, will still result in a reject if any of the included promises return an error.

How do we do it before?

Prior to the introduction of Promise.any the pattern for accomplishing this functionality looked something like this.

constp1=newPromise(/* ... */);constp2=newPromise(/* ... */);constpromises=2;consterrorList=[];letresult=null;constthenFn=(r)=>{if(result)return;result=r;/* do something with result */}consterrorHandler=(err)=>{if(errorList.length!==promises){returnerrorList.push(err);}/* handle all errors in errorList */}p1.then(thenFn).catch(errorHandler);p2.then(thenFn).catch(errorHandler);

How can we do it now?

With Promise.any the syntax to accomplish the same thing looks like this. It is similar to using Promise.race or Promise.all.

constp1=newPromise(/* ... */);constp2=newPromise(/* ... */);constpromises=[p1,p2];Promise.any(promises).then(firstResult=>{/* do whatever */}).catch(allErrors=>{/* do whatever */})// or when using async/awaittry{constfirstResult=awaitPromise.any(promises);/* do whatever */}catch(allErrors){/* do whatever */}

In what situation would we want to use this?

Let's say you want to fetch several sources of data, including data coming from Cache API. The goal is to retrieve the data as quickly as possible, but you don't need to retrieve it more than once.

try{consturl='https://example.com/api/v1/some-endpoint/data';constdata=awaitPromise.any([fetch(url),fetch('https://example.com/api/v1/some-endpoint-that-hopefully-is-near/data'),cache.match(url)]);/* render back to browser */}catch(errors){/* render all error or a general error */}