Coisas importantes a entender aqui
As funções thene catchretornam novos objetos de promessa.
Lançar ou rejeitar explicitamente, moverá a promessa atual para o estado rejeitado.
Como thene catchretornar novos objetos de promessa, eles podem ser encadeados.
Se você lançar ou rejeitar dentro de um manipulador de promessa ( thenou catch), ele será tratado no próximo manipulador de rejeição no caminho de encadeamento.
Conforme mencionado por jfriend00, os manipuladores thene catchnão são executados de forma síncrona. Quando um manipulador lança, ele termina imediatamente. Portanto, a pilha será desenrolada e a exceção será perdida. É por isso que lançar uma exceção rejeita a promessa atual.
No seu caso, você está rejeitando do1por dentro jogando um Errorobjeto. Agora, a promessa atual estará no estado rejeitado e o controle será transferido para o próximo manipulador, que é o thennosso caso.
Como o thenmanipulador não possui um manipulador de rejeição, do2ele não será executado. Você pode confirmar isso usando console.logdentro dele. Como a promessa atual não possui um manipulador de rejeição, ela também será rejeitada com o valor de rejeição da promessa anterior e o controle será transferido para o próximo manipulador que é catch.
Como catché um manipulador de rejeição, quando você faz console.log(err.stack);dentro dele, é possível ver o rastreamento da pilha de erros. Agora, você está jogando um Errorobjeto para que a promessa retornada catchtambém esteja no estado rejeitado.
Como você não anexou nenhum manipulador de rejeição ao catch, não é possível observar a rejeição.
Você pode dividir a cadeia e entender isso melhor, assim
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);
});
A saída que você obterá será algo como
Promise Promise { <rejected> [Error: do1] }
Promise1 Promise { <rejected> [Error: do1] }
Dentro do catchmanipulador 1, você está recebendo o valor do promiseobjeto como rejeitado.
Da mesma forma, a promessa retornada pelo catchmanipulador 1 também é rejeitada com o mesmo erro com o qual o promisefoi rejeitado e estamos observando-o no segundo catchmanipulador.
.catch(…)retorna.