Um dos maiores problemas com o uso de callbacks em operações assíncronas é o conhecido como callback hell . Ele acaba tornando seu código horizontal, dificultando a legibilidade.
Copy faç aAlgo ( function (resultado) {
faç aOutraCoisa (resultado , function (novoResultado) {
faç aOutraCoisaDiferente (novoResultado , function (resultadoFinal) {
console .log ( `Resultado final: ${ resultadoFinal } ` );
} , callbackErro);
} , callbackErro);
} , callbackErro);
Para contornar esse (e outros) problema(s) foram idealizadas as Promises que, por meio do chamado chaining , contornam o callback hell.
Copy faç aAlgo ()
.then ( function (resultado) {
return faç aOutraCoisa (resultado);
})
.then ( function (novoResultado) {
return faç aOutraCoisaDiferente (novoResultado)
})
.then ( function (resultadoFinal) {
console .log ( `Resultado final: ${ resultadoFinal } ` );
})
.catch (callbackErro);
Mesmo com o exemplo acima sendo pequeno, fica claro o ganho de legibilidade com o uso de chaining em Promises ao invés do callback hell.
Um erro comum é tentar fazer promise chaining adicionando varios .then a uma mesma promise.
Copy const promise = new Promise ( function (resolve , reject) {
setTimeout ( function () {
resolve ( 1 );
} , 1 );
});
promise .then ( function (resultado) {
console .log (resultado); // 1
return resultado + 1 ;
});
promise .then ( function (resultado) {
console .log (resultado); // 1
return resultado + 1 ;
});
promise .then ( function (resultado) {
console .log (resultado); // 1
return resultado + 1 ;
});
Como não esta sendo feito o chaining e sim apenas adicionando varios .then() na promise, a execução desses .then() é feita de forma independente.
Tambem é possivel retornar uma promise dentro de outra promise.
Copy new Promise ( function (resolve , reject) {
setTimeout ( function () {
return resolve ( 1 );
} , 1 );
}) .then ( function (resultado) {
console .log (resultado); // 1
return new Promise ( function (resolve , reject) {
return setTimeout ( function () {
return resolve (resultado + 1 );
} , 1 );
});
}) .then ( function (resultado) {
console .log (resultado); // 2
return new Promise ( function (resolve , reject) {
return setTimeout ( function () {
return resolve (resultado + 1 );
} , 1 );
});
}) .then ( function (resultado) {
console .log (resultado); // 3
});