Obietnice można „obsłużyć” po ich odrzuceniu. Oznacza to, że można wywołać wywołanie zwrotne odrzucenia obietnicy przed udostępnieniem modułu obsługi przechwytywania. To zachowanie jest dla mnie trochę uciążliwe, ponieważ można pisać ...
var promise = new Promise(function(resolve) {
kjjdjf(); // this function does not exist });
... iw tym przypadku obietnica zostaje odrzucona w milczeniu. Jeśli zapomnisz dodać moduł obsługi przechwytywania, kod będzie działał w trybie cichym bez błędów. Może to prowadzić do utrzymujących się i trudnych do znalezienia błędów.
W przypadku Node.js mówi się o obsłudze tych nieobsługiwanych odrzuceń Promise i zgłaszaniu problemów. To prowadzi mnie do ES7 async / czekaj. Rozważ ten przykład:
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;
}
W powyższym przykładzie załóżmy, że toothPromise został odrzucony (Błąd: z pasty do zębów!), Zanim getRoomTemperature został spełniony. W takim przypadku nastąpi nieobsługiwane odrzucenie obietnicy do czasu oczekiwania na zęby Promise.
Chodzi mi o to ... jeśli weźmiemy pod uwagę nieobsługiwane odrzucenie obietnicy jako problem, obietnice, które są później obsługiwane przez oczekiwanie, mogą zostać przypadkowo zgłoszone jako błędy. Z drugiej strony, jeśli uznamy, że odrzucenie odrzuconych obietnic nie jest problematyczne, uzasadnione błędy mogą nie zostać zgłoszone.
Myśli na ten temat?
Jest to związane z dyskusją w projekcie Node.js tutaj:
Domyślne zachowanie wykrywania nieobsługiwanego odrzucenia
jeśli napiszesz kod w ten sposób:
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
}
Wywołanie getReadyForBed spowoduje synchroniczne utworzenie ostatecznej (nie zwróconej) obietnicy - która będzie miała taki sam błąd „nieobsługiwanego odrzucenia” jak każda inna obietnica (oczywiście może to być nic, w zależności od silnika). (Uważam za bardzo dziwne, że twoja funkcja nic nie zwraca, co oznacza, że twoja funkcja asynchroniczna daje obietnicę dla niezdefiniowanej.
Jeśli złożę teraz obietnicę bez połowu i dodam ją później, większość implementacji „nieobsługiwanego błędu odrzucenia” faktycznie cofnie to ostrzeżenie, gdy później to zrobię. Innymi słowy, asynchronizacja / oczekiwanie nie zmienia dyskusji o „nieobsługiwanym odrzuceniu” w żaden sposób, jaki widzę.
aby uniknąć tej pułapki, napisz kod w ten sposób:
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);
}
Pamiętaj, że powinno to zapobiegać wszelkim nieobsługiwanym odrzuceniu obietnicy.