Lo return
scopo è di terminare l'esecuzione della funzione dopo il rifiuto e impedire l'esecuzione del codice dopo di essa.
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);
});
}
In questo caso impedisce l' resolve(numerator / denominator);
esecuzione, il che non è strettamente necessario. Tuttavia, è ancora preferibile terminare l'esecuzione per prevenire una possibile trappola in futuro. Inoltre, è una buona pratica impedire inutilmente l'esecuzione del codice.
sfondo
Una promessa può essere in uno dei 3 stati:
- in sospeso - stato iniziale. Da in attesa possiamo spostarci in uno degli altri stati
- adempiuto - operazione riuscita
- rifiutato - operazione fallita
Quando una promessa viene adempiuta o respinta, rimarrà in questo stato indefinitamente (risolto). Pertanto, il rifiuto di una promessa mantenuta o l'adempimento di una promessa respinta non avranno effetto.
Questo frammento di esempio mostra che sebbene la promessa sia stata mantenuta dopo essere stata respinta, è rimasta respinta.
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));
Quindi perché dobbiamo tornare?
Sebbene non possiamo modificare uno stato promesso stabile, il rifiuto o la risoluzione non interromperà l'esecuzione del resto della funzione. La funzione può contenere codice che creerà risultati confusi. Per esempio:
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));
Anche se la funzione non contiene tale codice in questo momento, questo crea una possibile trappola futura. Un futuro refactor potrebbe ignorare il fatto che il codice viene ancora eseguito dopo che la promessa è stata respinta e sarà difficile eseguire il debug.
Interruzione dell'esecuzione dopo la risoluzione / rifiuto:
Questo è materiale standard per il flusso di controllo JS.
- Ritorna dopo il
resolve
/ reject
:
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));
- Restituisci con
resolve
/ reject
- poiché il valore restituito del callback viene ignorato, possiamo salvare una riga restituendo la dichiarazione di rifiuto / risoluzione:
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));
- Utilizzando un blocco 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));
Preferisco usare una delle return
opzioni in quanto il codice è più piatto.