Cose importanti da capire qui
Sia i then
e catch
funzioni restituiscono nuovi oggetti promessa.
O il lancio o il rifiuto esplicito, sposteranno la promessa corrente allo stato rifiutato.
Poiché then
e catch
restituiscono nuovi oggetti di promessa, possono essere concatenati.
Se si lancia o si respinge all'interno di un gestore promessa (then
o catch
), questo verrà gestito nel successivo gestore di rifiuto lungo il percorso di concatenamento.
Come menzionato da jfriend00, i gestori then
e catch
non vengono eseguiti in modo sincrono. Quando un handler lancia, finirà immediatamente. Quindi, lo stack verrà svolto e l'eccezione verrà persa. Ecco perché lanciare un'eccezione rifiuta l'attuale promessa.
Nel tuo caso, si stanno rifiutando all'interno do1
lanciando un oggetto Error
. Ora, la promessa corrente sarà in stato rifiutato e il controllo sarà trasferito al gestore successivo, che è then
nel nostro caso.
Poiché il gestore then
non ha un gestore di rifiuto, lo do2
non verrà eseguito affatto. È possibile confermare questo utilizzando console.log
al suo interno. Poiché la promessa corrente non ha un gestore di rifiuto, sarà anche respinta con il valore di rifiuto dalla precedente promessa e il controllo sarà trasferito al gestore successivo che è catch
.
Poiché catch
è un gestore di rifiuto, quando si esegue console.log(err.stack);
al suo interno, è possibile visualizzare la traccia dello stack degli errori. Ora stai lanciando un oggetto Error
così la promessa restituita da catch
sarà anch'essa in stato rifiutato.
Poiché non è stato applicato alcun gestore di rifiuto allo catch
, non è possibile osservare il rifiuto.
È possibile dividere la catena e capire meglio, come questo
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'uscita si otterrà sarà qualcosa di simile a
Promise Promise { <rejected> [Error: do1] }
Promise1 Promise { <rejected> [Error: do1] }
All'interno del catch
gestore 1, si sono ottenendo il valore dell'oggetto promise
come rifiutato.
Allo stesso modo, la promessa restituito dal gestore catch
1, è anche respinto con lo stesso errore con cui il promise
è stata respinta e ci stanno osservando nel secondo catch
gestore.
Non viene inghiottito da un buco nero. Rifiuta la promessa che '.catch (...)' ritorna. – Bergi
Vedere anche [Perché le eccezioni sono utilizzate per rifiutare le promesse in JS?] (Http://stackoverflow.com/q/21616432/1048572) e [Come gestisco le eccezioni globalmente con promesse native in io.js/node.js? ] (http://stackoverflow.com/q/28709666/1048572) – Bergi