Cosas importantes para entender aquí
Ambas funciones theny catchdevuelven nuevos objetos de promesa.
Ya sea arrojando o rechazando explícitamente, se moverá la promesa actual al estado rechazado.
Desde theny catchdevolver nuevos objetos de promesa, se pueden encadenar.
Si arroja o rechaza dentro de un controlador de promesa ( theno catch), se manejará en el siguiente controlador de rechazo por el camino de encadenamiento.
Como mencionó jfriend00, los controladores theny catchno se ejecutan sincrónicamente. Cuando un controlador lanza, llegará a su fin de inmediato. Por lo tanto, la pila se desenrollará y se perderá la excepción. Es por eso que lanzar una excepción rechaza la promesa actual.
En su caso, está rechazando dentro do1arrojando un Errorobjeto. Ahora, la promesa actual estará en estado rechazado y el control se transferirá al siguiente controlador, que es thenen nuestro caso.
Como el thencontrolador no tiene un controlador de rechazo, do2no se ejecutará en absoluto. Puede confirmar esto usando console.logdentro de él. Dado que la promesa actual no tiene un controlador de rechazo, también se rechazará con el valor de rechazo de la promesa anterior y el control se transferirá al siguiente controlador que sea catch.
Como catches un controlador de rechazo, cuando lo haces console.log(err.stack);dentro de él, puedes ver el seguimiento de la pila de errores. Ahora, está arrojando un Errorobjeto para que la promesa devuelta catchtambién esté en estado rechazado.
Como no ha adjuntado ningún controlador de rechazo al catch, no puede observar el rechazo.
Puedes dividir la cadena y entender esto mejor, así
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);
});
La salida que obtendrás será algo así como
Promise Promise { <rejected> [Error: do1] }
Promise1 Promise { <rejected> [Error: do1] }
Dentro del catchcontrolador 1, está obteniendo el valor del promiseobjeto como rechazado.
Del mismo modo, la promesa devuelta por el catchcontrolador 1 también se rechaza con el mismo error con el que promisese rechazó y la estamos observando en el segundo catchcontrolador.
.catch(…)vuelve.