Quindi, in pratica stai chiedendo qual è la differenza tra questi due (dov'è p
una promessa creata da un codice precedente):
return p.then(...).catch(...);
e
return p.catch(...).then(...);
Ci sono differenze quando p risolve o rifiuta, ma se tali differenze contano o meno dipende da ciò che fa il codice all'interno dei gestori .then()
o .catch()
.
Cosa succede quando si p
risolve:
Nel primo schema, quando si p
risolve, .then()
viene chiamato il gestore. Se quel .then()
gestore restituisce un valore o un'altra promessa che alla fine si risolve, il .catch()
gestore viene ignorato. Ma, se il .then()
gestore lancia o restituisce una promessa che alla fine rifiuta, allora il .catch()
gestore eseguirà sia un rifiuto nella promessa originale p
, ma anche un errore che si verifica nel .then()
gestore.
Nel secondo schema, quando si p
risolve, .then()
viene chiamato il gestore. Se quel .then()
gestore lancia o restituisce una promessa che alla fine rifiuta, allora il .catch()
gestore non può prenderla perché è prima di essa nella catena.
Quindi, questa è la differenza n. 1. Se il .catch()
gestore è DOPO, può anche rilevare errori all'interno del .then()
gestore.
Cosa succede quando p
rifiuta:
Ora, nel primo schema, se la promessa viene p
rifiutata, il .then()
gestore viene ignorato e il .catch()
gestore verrà chiamato come ci si aspetterebbe. Quello che fai nel .catch()
gestore determina cosa viene restituito come risultato finale. Se restituisci semplicemente un valore dal .catch()
gestore o restituisci una promessa che alla fine si risolve, la catena della promessa passa allo stato risolto perché hai "gestito" l'errore e hai restituito normalmente. Se lanci o restituisci una promessa rifiutata nel .catch()
conduttore, la promessa restituita rimane rifiutata.
Nel secondo schema, se la promessa viene p
rifiutata, .catch()
viene chiamato il gestore. Se restituisci un valore normale o una promessa che alla fine si risolve dal .catch()
gestore (quindi "gestendo" l'errore), la catena della promessa passa allo stato risolto e il .then()
gestore dopo .catch()
verrà chiamato.
Quindi questa è la differenza n. 2. Se il .catch()
gestore è PRIMA, può gestire l'errore e consentire al .then()
gestore di essere comunque chiamato.
Quando usarlo:
Usa il primo schema se vuoi un solo .catch()
gestore in grado di rilevare errori nella promessa originale p
o nel .then()
gestore e un rifiuto da p
dovrebbe saltare il .then()
gestore.
Usa il secondo schema se vuoi essere in grado di rilevare gli errori nella promessa originale p
e forse (a seconda delle condizioni), consentire alla catena della promessa di continuare come risolta, eseguendo così il .then()
gestore.
L'altra opzione
C'è un'altra opzione per utilizzare entrambi i callback a cui puoi passare .then()
come in:
p.then(fn1, fn2)
Ciò garantisce che solo uno di fn1
o fn2
verrà mai chiamato. Se si p
risolve, fn1
verrà chiamato. Se p
rifiuta, fn2
verrà chiamato. Nessun cambiamento di risultato fn1
potrà mai fn2
farti chiamare o viceversa. Quindi, se vuoi essere assolutamente sicuro che solo uno dei tuoi due gestori venga chiamato indipendentemente da ciò che accade negli stessi gestori, puoi usare p.then(fn1, fn2)
.