As promessas podem ser "tratadas" após serem rejeitadas. Ou seja, é possível chamar o retorno de chamada rejeitada de uma promessa antes de fornecer um manipulador de captura. Esse comportamento é um pouco incômodo para mim, porque se pode escrever ...
var promise = new Promise(function(resolve) {
kjjdjf(); // this function does not exist });
... e, neste caso, a promessa é rejeitada silenciosamente. Se alguém esquecer de adicionar um manipulador de captura, o código continuará sendo executado silenciosamente, sem erros. Isso pode levar a erros persistentes e difíceis de encontrar.
No caso do Node.js, fala-se em lidar com essas rejeições não tratadas do Promise e em relatar os problemas. Isso me leva ao ES7 assíncrono / aguardado. Considere este exemplo:
async function getReadyForBed() {
let teethPromise = brushTeeth();
let tempPromise = getRoomTemperature();
// Change clothes based on room temperature
let temp = await tempPromise;
// Assume `changeClothes` also returns a Promise
if(temp > 20) {
await changeClothes("warm");
} else {
await changeClothes("cold");
}
await teethPromise;
}
No exemplo acima, suponha que teethPromise foi rejeitado (Erro: sem pasta de dente!) Antes que getRoomTemperature fosse atendido. Nesse caso, haveria uma rejeição não tratada da promessa até aguardar os dentes.
O que quero dizer é que ... se considerarmos que as rejeições de Promessa não tratadas são um problema, promessas que são tratadas posteriormente por uma espera podem ser inadvertidamente relatadas como bugs. Por outro lado, se considerarmos que as rejeições por promessa não tratadas não são problemáticas, os erros legítimos podem não ser relatados.
Pensamentos sobre isso?
Isso está relacionado à discussão encontrada no projeto Node.js. aqui:
Comportamento de detecção de rejeição não tratada padrão
se você escrever o código desta maneira:
function getReadyForBed() {
let teethPromise = brushTeeth();
let tempPromise = getRoomTemperature();
// Change clothes based on room temperature
return Promise.resolve(tempPromise)
.then(temp => {
// Assume `changeClothes` also returns a Promise
if (temp > 20) {
return Promise.resolve(changeClothes("warm"));
} else {
return Promise.resolve(changeClothes("cold"));
}
})
.then(teethPromise)
.then(Promise.resolve()); // since the async function returns nothing, ensure it's a resolved promise for `undefined`, unless it's previously rejected
}
Quando getReadyForBed é chamado, ele cria de forma síncrona a promessa final (não retornada) - que terá o mesmo erro de "rejeição sem tratamento" que qualquer outra promessa (pode não ser nada, é claro, dependendo do mecanismo). (Acho muito estranho que sua função não retorne nada, o que significa que sua função assíncrona produz uma promessa indefinida.
Se eu fizer uma Promessa agora sem uma captura e adicionar uma mais tarde, a maioria das implementações de "erro de rejeição sem tratamento" retrairá o aviso quando eu o tratar posteriormente. Em outras palavras, async / waitit não altera a discussão sobre "rejeição sem tratamento" de qualquer maneira que eu possa ver.
Para evitar essa armadilha, escreva o código desta maneira:
async function getReadyForBed() {
let teethPromise = brushTeeth();
let tempPromise = getRoomTemperature();
// Change clothes based on room temperature
var clothesPromise = tempPromise.then(function(temp) {
// Assume `changeClothes` also returns a Promise
if(temp > 20) {
return changeClothes("warm");
} else {
return changeClothes("cold");
}
});
/* Note that clothesPromise resolves to the result of `changeClothes`
due to Promise "chaining" magic. */
// Combine promises and await them both
await Promise.all(teethPromise, clothesPromise);
}
Observe que isso deve impedir qualquer rejeição de promessa não tratada.