早期解決/拒否後に返品する必要はありますか? 質問する

早期解決/拒否後に返品する必要はありますか? 質問する

次のようなコードがあるとします。

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 つの状態のいずれかになります。

  1. 保留中 - 初期状態。保留中から他の状態のいずれかに移行できます。
  2. 達成 - 操作が成功しました
  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コードがよりフラットなので、いずれかのオプションを使用することを好みます。

おすすめ記事