JavaScript Promise API
Impara la JavaScript Promise API: Promise.all, allSettled, race, any, resolve e reject. Confronta fast-fail e allSettled con esempi eseguibili e una tabella su quando usare quale.
La classe Promise include diversi metodi statici per combinare e creare promise. Invece di collegare manualmente più catene .then(), si passa un array di promise a un combinatore e si ottiene una singola promise che si risolve quando il gruppo raggiunge uno stato definito.
Questa pagina descrive i quattro combinatori — Promise.all, Promise.allSettled, Promise.race e Promise.any — oltre ai due helper di creazione Promise.resolve e Promise.reject. Se sei nuovo alle promise, inizia prima con JavaScript: Promises.
Gli esempi seguenti usano
.then()/.catch()per rendere esplicito il flusso di controllo. Nel codice reale si leggerebbe normalmente il risultato conasync/await.
Scegliere il combinatore giusto
| Metodo | Si risolve quando… | Rifiuta quando… | Uso tipico |
|---|---|---|---|
Promise.all | tutte le promise vengono soddisfatte | una qualsiasi promise rifiuta (fast-fail) | Hai bisogno di ogni risultato e un errore deve interrompere tutto |
Promise.allSettled | tutte le promise si stabilizzano (non rifiuta mai) | — | Vuoi ogni esito, successo o fallimento |
Promise.race | la prima promise si stabilizza (soddisfatta o rifiutata) | la prima promise rifiuta per prima | Timeout, "vince il primo a rispondere" |
Promise.any | la prima promise viene soddisfatta | tutte le promise rifiutano | Primo risultato con successo, ignora i fallimenti individuali |
La distinzione chiave: Promise.all va in fast-fail — rifiuta nell'istante in cui qualsiasi input rifiuta, anche se altre promise sono ancora in sospeso. Se invece vuoi attendere ogni promise indipendentemente da tutto, usa Promise.allSettled.
Utilizzare Promise.all per Attività Concorrenti
Promise.all è un metodo essenziale per gestire più promise in modo concorrente. Quando hai bisogno di eseguire diverse operazioni asincrone e procedere solo quando tutte sono state completate con successo, Promise.all è lo strumento che ti serve.
Come implementare Promise.all
Di seguito un esempio che mostra come usare Promise.all per gestire più richieste API simultaneamente:
In questo esempio, Promise.all accetta un array di promise e si risolve in un array dei loro risultati nello stesso ordine dell'input (non nell'ordine in cui sono terminate). Se una qualsiasi promise rifiuta, Promise.all rifiuta immediatamente con il motivo di quel primo rifiuto — i risultati delle altre vengono scartati. Vedi Gestione degli errori con le promise per sapere come recuperare da tali fallimenti.
Padroneggiare Promise.allSettled
A differenza di Promise.all, il metodo Promise.allSettled restituisce una promise che si risolve dopo che tutte le promise fornite si sono risolte o rifiutate, con un array di oggetti che descrivono ciascuno l'esito di ogni promise.
Esempio di Promise.allSettled
Ecco come puoi usare Promise.allSettled:
Nota: Promise.allSettled non rifiuta mai. Si risolve sempre con un array di oggetti risultato, ciascuno contenente una proprietà status ('fulfilled' o 'rejected') e una proprietà value o reason.
Questo metodo è particolarmente utile quando devi garantire che tutte le promise procedano fino al completamento indipendentemente dal fatto che vengano soddisfatte o rifiutate.
Implementare Promise.race
Promise.race è un altro potente strumento che consente di gestire più promise risolvendo o rifiutando non appena una delle promise nell'iterabile si risolve o rifiuta.
Come usare Promise.race
Di seguito un'applicazione pratica di Promise.race:
Questo metodo è ideale per scenari in cui hai bisogno del risultato più veloce tra più operazioni asincrone — ad esempio, mettere in gara una richiesta contro una promise di timeout. Nota che race si stabilizza sulla prima promise che si stabilizza, sia che venga soddisfatta o rifiutata.
Ottenere il Primo Successo con Promise.any
Promise.any è la controparte ottimista di Promise.race. Ignora i rifiuti e si risolve con il valore della prima promise che viene soddisfatta. Rifiuta solo se tutte le promise rifiutano, nel qual caso lancia un AggregateError la cui proprietà .errors contiene tutti i motivi individuali.
Come usare Promise.any
Usa Promise.any quando hai diverse fonti per gli stessi dati (ad esempio server mirror) e ti interessa solo il primo che ha successo.
Creare Promise con resolve e reject
Promise.resolve(value) e Promise.reject(reason) sono scorciatoie per costruire una promise già stabilizzata senza il boilerplate new Promise(executor).
Promise.resolve(value)restituisce una promise già soddisfatta convalue. Sevalueè a sua volta un thenable, viene "adottato" e seguito.Promise.reject(reason)restituisce una promise già rifiutata conreason.
Questi helper sono comunemente usati per restituire un valore memorizzato nella cache da una funzione altrimenti asincrona, o per avviare una catena .then().
Creare un Polyfill per Promise.allSettled
Non tutti gli ambienti supportano Promise.allSettled nativamente. Pertanto, implementare un polyfill può garantire la compatibilità tra diversi ambienti JavaScript.
Polyfill per Promise.allSettled
Ecco come puoi creare un semplice polyfill:
Questo polyfill fornisce una funzionalità di base in cui ogni promise viene gestita individualmente e risolta nel proprio esito, garantendo che il comportamento di allSettled venga emulato in modo efficace.
Integrando queste tecniche avanzate sulle promise e comprendendo i meccanismi sottostanti dei polyfill, puoi elevare il tuo codice JavaScript a nuovi livelli. Questi metodi non solo migliorano l'affidabilità del codice, ma offrono anche un controllo raffinato sulle operazioni asincrone, aprendo la strada ad applicazioni web più robuste.