return
Celem jest, aby zakończyć wykonywanie funkcji po odrzuceniu i zapobiec wykonanie kodu po niej.
function divide(numerator, denominator) {
return new Promise((resolve, reject) => {
if (denominator === 0) {
reject("Cannot divide by 0");
return; // The function execution ends here
}
resolve(numerator / denominator);
});
}
W takim przypadku uniemożliwia resolve(numerator / denominator);
wykonanie polecenia, które nie jest ściśle potrzebne. Jednak nadal lepiej jest zakończyć wykonywanie, aby zapobiec możliwej pułapce w przyszłości. Ponadto dobrą praktyką jest zapobieganie niepotrzebnemu uruchamianiu kodu.
tło
Obietnica może być w jednym z 3 stanów:
- w toku - stan początkowy. Z oczekujących możemy przejść do jednego z pozostałych stanów
- spełnione - udane działanie
- odrzucone - operacja zakończona niepowodzeniem
Kiedy obietnica zostanie spełniona lub odrzucona, pozostanie w tym stanie na czas nieokreślony (rozliczony). Odrzucenie spełnionej obietnicy lub spełnienie odrzuconej obietnicy nie przyniesie skutku.
Ten przykładowy fragment pokazuje, że chociaż obietnica została spełniona po odrzuceniu, pozostała odrzucona.
function divide(numerator, denominator) {
return new Promise((resolve, reject) => {
if (denominator === 0) {
reject("Cannot divide by 0");
}
resolve(numerator / denominator);
});
}
divide(5,0)
.then((result) => console.log('result: ', result))
.catch((error) => console.log('error: ', error));
Dlaczego więc musimy wrócić?
Chociaż nie możemy zmienić ustalonego stanu przyrzeczenia, odrzucenie lub rozstrzygnięcie nie zatrzyma wykonania pozostałej części funkcji. Funkcja może zawierać kod, który spowoduje mylące wyniki. Na przykład:
function divide(numerator, denominator) {
return new Promise((resolve, reject) => {
if (denominator === 0) {
reject("Cannot divide by 0");
}
console.log('operation succeeded');
resolve(numerator / denominator);
});
}
divide(5, 0)
.then((result) => console.log('result: ', result))
.catch((error) => console.log('error: ', error));
Nawet jeśli funkcja nie zawiera obecnie takiego kodu, tworzy to potencjalną pułapkę na przyszłość. Przyszły refaktor może zignorować fakt, że kod jest nadal wykonywany po odrzuceniu obietnicy i będzie trudny do debugowania.
Zatrzymywanie wykonywania po rozwiązaniu / odrzuceniu:
Jest to standardowy przepływ kontroli JS.
function divide(numerator, denominator) {
return new Promise((resolve, reject) => {
if (denominator === 0) {
reject("Cannot divide by 0");
return;
}
console.log('operation succeeded');
resolve(numerator / denominator);
});
}
divide(5, 0)
.then((result) => console.log('result: ', result))
.catch((error) => console.log('error: ', error));
- Zwróć za pomocą
resolve
/ reject
- ponieważ zwracana wartość wywołania zwrotnego jest ignorowana, możemy zapisać linię, zwracając instrukcję odrzucenia / rozwiązania:
function divide(numerator, denominator) {
return new Promise((resolve, reject) => {
if (denominator === 0) {
return reject("Cannot divide by 0");
}
console.log('operation succeeded');
resolve(numerator / denominator);
});
}
divide(5, 0)
.then((result) => console.log('result: ', result))
.catch((error) => console.log('error: ', error));
- Korzystanie z bloku if / else:
function divide(numerator, denominator) {
return new Promise((resolve, reject) => {
if (denominator === 0) {
reject("Cannot divide by 0");
} else {
console.log('operation succeeded');
resolve(numerator / denominator);
}
});
}
divide(5, 0)
.then((result) => console.log('result: ', result))
.catch((error) => console.log('error: ', error));
Wolę użyć jednej z return
opcji, ponieważ kod jest bardziej płaski.