Sou novo no JS Promises e estou tentando entender por que obtenho resultados diferentes dependendo se tenho um retorno ou não nesta linha: return foo(2).then(() => {
function foo(num) {
console.log(num)
return new Promise(resolve => setTimeout(resolve, num * 1000));
}
foo(1).then(() => {
return foo(2).then(() => {
console.log(4)
});
}).then(() => {
foo(3)
})
contra
function foo(num) {
console.log(num)
return new Promise(resolve => setTimeout(resolve, num * 1000));
}
foo(1).then(() => {
foo(2).then(() => {
console.log(4)
});
}).then(() => {
foo(3)
})
Por que a ordem de 4/3 muda?
Chamar
.then(someFn)
cria uma nova promessa. Essa promessa resolverá o que quer quesomeFn
retorne. SesomeFn
retornarundefined
, como no seu segundo exemplo, a nova promessa poderá ser resolvidaundefined
imediatamente. SesomeFn
retornar uma promessa, como no seu primeiro exemplo, então ela deverá esperar que a promessa interna seja resolvida, antes que a promessa externa saiba com qual valor deve ser resolvida.Resumindo: se você retribui uma promessa interior, você força a promessa exterior a esperar por ela.
A diferença de comportamento se deve à forma como as promessas encadeiam e retornam valores.
RETORNO DE PROMESSA INTERNA
foo(1) inicia e imprime 1. Ele retorna uma promessa que é resolvida após 1 segundo. Após 1 segundo, o primeiro então é chamado. Ele retorna a promessa de foo(2). foo(2) inicia e imprime 2. Ele retorna uma promessa que é resolvida após 2 segundos. Após 2 segundos, o interno imprime 4.
O externo então espera que o interno seja concluído porque a promessa interna foi devolvida. Depois que a promessa interna é resolvida, a externa é executada. FinallSy, foo(3) inicia e imprime 3.
NÃO DEVOLVER A PROMESSA INTERIOR
foo(1) inicia e imprime 1. Ele retorna uma promessa que é resolvida após 1 segundo Após 1 segundo, o primeiro then é chamado, foo(2) inicia e imprime 2. Ele retorna uma promessa que é resolvida após 2 segundos, mas esta promessa não é devolvido ao exterior então. O exterior então não espera que foo(2) seja concluído e prossegue imediatamente. foo(3) inicia e imprime 3 após a resolução da primeira promessa, sem esperar que foo(2) seja concluído. Após 2 segundos do início de foo(2), o inner imprime 4.
devolvendo a promessa interna O externo então espera que a promessa interna seja resolvida antes de prosseguir. para que foo(3) seja executado após a conclusão de foo(1) e foo(2). quando não retorna a promessa interna, o externo não espera que a promessa interna seja resolvida, então foo(3) é executado assim que foo(1) é concluído, independentemente de foo(2).