Coisas importantes a entender aqui
As funções then
e catch
retornam novos objetos de promessa.
Lançar ou rejeitar explicitamente, moverá a promessa atual para o estado rejeitado.
Como then
e catch
retornar novos objetos de promessa, eles podem ser encadeados.
Se você lançar ou rejeitar dentro de um manipulador de promessa ( then
ou catch
), ele será tratado no próximo manipulador de rejeição no caminho de encadeamento.
Conforme mencionado por jfriend00, os manipuladores then
e catch
nã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 do1
por dentro jogando um Error
objeto. Agora, a promessa atual estará no estado rejeitado e o controle será transferido para o próximo manipulador, que é o then
nosso caso.
Como o then
manipulador não possui um manipulador de rejeição, do2
ele não será executado. Você pode confirmar isso usando console.log
dentro 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 Error
objeto para que a promessa retornada catch
també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 catch
manipulador 1, você está recebendo o valor do promise
objeto como rejeitado.
Da mesma forma, a promessa retornada pelo catch
manipulador 1 também é rejeitada com o mesmo erro com o qual o promise
foi rejeitado e estamos observando-o no segundo catch
manipulador.
.catch(…)
retorna.