次のようなコードがあるとします。
function divide(numerator, denominator) {
return new Promise((resolve, reject) => {
if(denominator === 0){
reject("Cannot divide by 0");
return; //superfluous?
}
resolve(numerator / denominator);
});
}
早期終了するためにを使用することが目的である場合、その直後に を使用することもreject
習慣にする必要がありますか?return
ベストアンサー1
目的return
は、拒否後に関数の実行を終了し、その後のコード実行を防止することです。
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);
});
}
この場合、resolve(numerator / denominator);
実行が阻止されますが、これは厳密には必要ではありません。ただし、将来起こり得るトラップを防ぐために、実行を終了することが望ましいです。また、不必要にコードが実行されないようにすることも良い方法です。
背景
プロミスは次の 3 つの状態のいずれかになります。
- 保留中 - 初期状態。保留中から他の状態のいずれかに移行できます。
- 達成 - 操作が成功しました
- 拒否 - 操作に失敗しました
約束が履行または拒否されると、その状態は無期限に維持されます (解決済み)。したがって、履行された約束を拒否したり、拒否された約束を履行したりしても効果はありません。
この例のスニペットは、Promise が拒否された後も履行されたにもかかわらず、拒否されたままになっていることを示しています。
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));
では、なぜ戻る必要があるのでしょうか?
解決済みの Promise の状態を変更することはできませんが、拒否または解決しても関数の残りの部分の実行は停止しません。関数には、混乱を招く結果を生み出すコードが含まれている可能性があります。例:
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));
現時点では関数にそのようなコードが含まれていない場合でも、将来的に罠に陥る可能性があります。将来のリファクタリングでは、Promise が拒否された後もコードが実行されるという事実が無視される可能性があり、デバッグが困難になります。
解決/拒否後に実行を停止する:
これは標準的な JS 制御フローです。
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));
resolve
/で戻りますreject
- コールバックの戻り値は無視されるため、reject/resolve ステートメントを返すことで 1 行を節約できます。
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));
- 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));
return
コードがよりフラットなので、いずれかのオプションを使用することを好みます。