Cosas importantes para entender aquí
Ambas funciones then
y catch
devuelven nuevos objetos de promesa.
Ya sea arrojando o rechazando explícitamente, se moverá la promesa actual al estado rechazado.
Desde then
y catch
devolver nuevos objetos de promesa, se pueden encadenar.
Si arroja o rechaza dentro de un controlador de promesa ( then
o catch
), se manejará en el siguiente controlador de rechazo por el camino de encadenamiento.
Como mencionó jfriend00, los controladores then
y catch
no 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 do1
arrojando un Error
objeto. Ahora, la promesa actual estará en estado rechazado y el control se transferirá al siguiente controlador, que es then
en nuestro caso.
Como el then
controlador no tiene un controlador de rechazo, do2
no se ejecutará en absoluto. Puede confirmar esto usando console.log
dentro 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 catch
es 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 Error
objeto para que la promesa devuelta catch
tambié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 catch
controlador 1, está obteniendo el valor del promise
objeto como rechazado.
Del mismo modo, la promesa devuelta por el catch
controlador 1 también se rechaza con el mismo error con el que promise
se rechazó y la estamos observando en el segundo catch
controlador.
.catch(…)
vuelve.