Cosa c'è di sbagliato in questo?
Ma lo schema funziona!
Fortunato. Sfortunatamente, probabilmente no, dato che probabilmente hai dimenticato un caso limite. In più della metà degli eventi che ho visto, l'autore ha dimenticato di prendersi cura del gestore degli errori:
return new Promise(function(resolve) {
getOtherPromise().then(function(result) {
resolve(result.property.example);
});
})
Se l'altra promessa viene rifiutato, questo accadrà inosservato, invece di essere propagato per la nuova promessa (dove verrebbe gestito) - e la nuova promessa rimane sospesa per sempre, che può indurre fughe.
La stessa cosa accade nel caso in cui il codice di richiamata causi un errore - ad es. quando result
non ha un property
e viene generata un'eccezione. Ciò andrebbe non gestito e lascerà la nuova promessa irrisolta.
Al contrario, utilizzando .then()
non prendere automaticamente la cura di entrambi questi scenari, e respinge la nuova promessa quando si verifica un errore:
return getOtherPromise().then(function(result) {
return result.property.example;
})
L'antipattern differita non è solo ingombrante, ma anche soggetto ad errori . L'utilizzo di .then()
per il concatenamento è molto più sicuro.
Ma ho gestito tutto!
Davvero? Buona. Tuttavia, questo sarà abbastanza dettagliato e abbondante, specialmente se si utilizza una libreria di promessa che supporta altre funzionalità come la cancellazione o il passaggio di messaggi. O forse lo farà in futuro, o vuoi scambiare la tua biblioteca con una migliore? Non vorrai riscrivere il tuo codice per quello.
I metodi delle librerie (then
) non supportano solo in modo nativo tutte le funzionalità, ma potrebbero anche avere alcune ottimizzazioni in atto. Usarli probabilmente renderà il tuo codice più veloce, o almeno permetterà di essere ottimizzato dalle future revisioni della libreria.
Come posso evitarlo?
Così ogni volta che vi trovate a creare manualmente un Promise
o Deferred
e già sono coinvolti promesse esistenti, controllo la libreria API prima. L'antipattern Deferred è spesso applicato da persone che vedono le promesse [solo] come un modello osservatore - ma promises are more than callbacks: dovrebbero essere componibili. Ogni libreria decente ha molte funzioni facili da usare per la composizione delle promesse in ogni modo pensabile, avendo cura di tutte le cose di basso livello che non vuoi trattare.
Se hai trovato la necessità di comporre alcune promesse in un modo nuovo che non è supportato da una funzione di supporto esistente, la scrittura della propria funzione con Deferred inevitabili dovrebbe essere la tua ultima opzione. Prendi in considerazione il passaggio a una libreria più funzionale e/o un bug alla tua libreria corrente. Il suo manutentore dovrebbe essere in grado di ricavare la composizione dalle funzioni esistenti, implementare una nuova funzione di supporto per te e/o aiutare a identificare i casi limite che devono essere gestiti.
Posso confermare che la rimozione di questo è (nel contesto di destra, non a sinistra, esempio) rimuovere il wrapper di funzione 'getStuffDone' e utilizzare solo il letterale Promesso? –
o il blocco 'catch' nel wrapper' getStuffDone' è l'antipattern? –
Per qualche secondo, sono rimasto stupito dal fatto che @BenjaminGruenbaum avrebbe * fatto * una domanda sulle promesse invece di * rispondere * uno :) – max