Le promesse possono essere "gestite" dopo essere state respinte. Cioè, si può chiamare il richiamo del rifiuto di una promessa prima di fornire un gestore di cattura. Questo comportamento è un po 'fastidioso per me perché si può scrivere ...
var promise = new Promise(function(resolve) {
kjjdjf(); // this function does not exist });
... e in questo caso, la Promessa viene respinta silenziosamente. Se si dimentica di aggiungere un gestore catch, il codice continuerà a essere eseguito silenziosamente senza errori. Ciò potrebbe portare a bug persistenti e difficili da trovare.
Nel caso di Node.js, si parla di gestire questi rifiuti Promise non gestiti e di segnalare i problemi. Questo mi porta a ES7 async / waitit. Considera questo esempio:
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;
}
Nell'esempio sopra, supponiamo che i denti Promise siano stati respinti (errore: fuori dal dentifricio!) Prima che getRoomTemperature fosse realizzato. In questo caso, ci sarebbe un rifiuto Promesso non gestito fino ad attendere i denti.
Il mio punto è questo ... se consideriamo un problema il rifiuto delle promesse non gestite, le promesse che vengono successivamente gestite da un'attesa potrebbero essere segnalate inavvertitamente come bug. Inoltre, se consideriamo i rifiuti non gestiti non promettenti, i bug legittimi potrebbero non essere segnalati.
Pensi su questo?
Questo è legato alla discussione trovata nel progetto Node.js qui:
Comportamento rilevamento rifiuto non gestito predefinito
se scrivi il codice in questo modo:
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 viene richiamato getReadyForBed, questo creerà in modo sincrono la promessa finale (non restituita) - che avrà lo stesso errore di "rifiuto non gestito" di qualsiasi altra promessa (ovviamente potrebbe non essere nulla, a seconda del motore). (Trovo molto strano che la tua funzione non restituisca nulla, il che significa che la tua funzione asincrona produce una promessa per indefinito.
Se faccio una Promessa in questo momento senza una cattura e ne aggiungo una in seguito, la maggior parte delle implementazioni di "errore di rifiuto non gestito" ritrarrà effettivamente l'avviso quando lo gestirò in seguito. In altre parole, async / await non altera la discussione sul "rifiuto non gestito" in alcun modo che io possa vedere.
per evitare questo inconveniente, scrivere il codice in questo modo:
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);
}
Si noti che ciò dovrebbe impedire qualsiasi rifiuto non gestito della promessa.