Cose importanti da capire qui
Entrambe le funzioni then
e catch
restituiscono nuovi oggetti promessa.
Lanciare o rifiutare esplicitamente, sposterà la promessa attuale allo stato rifiutato.
Poiché then
e catch
restituiscono nuovi oggetti promessa, possono essere concatenati.
Se lanci o rifiuti all'interno di un gestore di promesse ( then
o catch
), verrà gestito nel successivo gestore di rifiuto lungo il percorso di concatenamento.
Come indicato da jfriend00, i gestori then
e catch
non vengono eseguiti in modo sincrono. Quando un gestore lancia, finirà immediatamente. Quindi, lo stack verrà srotolato e l'eccezione andrebbe persa. Ecco perché lanciare un'eccezione rifiuta l'attuale promessa.
Nel tuo caso, stai rifiutando dentro do1
lanciando un Error
oggetto. Ora, la promessa attuale sarà in stato respinto e il controllo verrà trasferito al gestore successivo, che è then
nel nostro caso.
Poiché il then
gestore non ha un gestore di rifiuto, do2
non verrà eseguito affatto. Puoi confermarlo usando console.log
al suo interno. Poiché la promessa corrente non ha un gestore di rifiuto, verrà rifiutata anche con il valore di rifiuto della promessa precedente e il controllo verrà trasferito al gestore successivo che è catch
.
Come catch
è un gestore di rifiuto, quando lo fai console.log(err.stack);
al suo interno, sei in grado di vedere la traccia dello stack degli errori. Ora, stai lanciando un Error
oggetto da esso, quindi anche la promessa restituita catch
sarà in stato rifiutato.
Poiché non è stato collegato alcun gestore di rifiuto a catch
, non è possibile osservare il rifiuto.
Puoi dividere la catena e capirlo meglio, in questo modo
var promise = do1().then(do2);
var promise1 = promise.catch(function (err) {
console.log("Promise", promise);
throw err;
});
promise1.catch(function (err) {
console.log("Promise1", promise1);
});
L'output che otterrai sarà qualcosa di simile
Promise Promise { <rejected> [Error: do1] }
Promise1 Promise { <rejected> [Error: do1] }
All'interno del catch
gestore 1, stai ottenendo il valore promise
dell'oggetto come rifiutato.
Allo stesso modo, anche la promessa restituita dal catch
gestore 1 viene respinta con lo stesso errore con il quale è promise
stata rifiutata e la osserviamo nel secondo catch
gestore.
.catch(…)
ritorna.