回答:
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);
、厳密には必要ありませんが、の実行が妨げられます。ただし、今後トラップが発生しないように、実行を終了することをお勧めします。さらに、コードを不必要に実行しないようにすることをお勧めします。
バックグラウンド
promiseは次の3つの状態のいずれかになります。
約束が履行または拒否されると、無期限にこの状態が維持されます(解決済み)。したがって、履行された約束を拒否したり、拒否された約束を履行したりしても効果はありません。
この例のスニペットは、拒否された後、約束は満たされましたが、拒否されたままであることを示しています。
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));
では、なぜ戻る必要があるのでしょうか。
確定済みのプロミス状態を変更することはできませんが、拒否または解決しても、残りの関数の実行は停止しません。関数には、紛らわしい結果を作成するコードが含まれている場合があります。例えば:
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));
現在関数にそのようなコードが含まれていない場合でも、これは将来起こり得るトラップを作成します。今後のリファクタリングでは、プロミスが拒否された後もコードが実行されるという事実を無視する可能性があり、デバッグが困難になります。
解決/拒否後に実行を停止する:
これは標準のJS制御フローに関するものです。
resolve
/の後に戻るreject
:resolve
/で戻るreject
-コールバックの戻り値は無視されるため、reject / resolveステートメントを返すことで行を保存できます。return
コードはよりフラットなので、私はオプションの1つを使用することを好みます。
return
存在するかどうかに関係なく、コードは実際には異なる動作をしないことに注意する価値があります。いったんpromise状態が設定されると変更できないため、呼び出しresolve()
後に呼び出しreject()
ても、追加のCPUサイクルをいくつか使用する以外は何もしません。私自身、return
コードの清潔さと効率の観点からだけを使用しますが、この特定の例では必要ありません。
Promise.try(() => { })
新しいPromiseの代わりに使用してみて、解決/拒否呼び出しの使用を避けます。代わりに、Promiseを開始する手段としてreturn denominator === 0 ? throw 'Cannot divide by zero' : numerator / denominator;
使用するだけでPromise.try
なく、問題のあるtry / catchブロックにラップされているpromiseを削除することもできます。
reject
にデータベースやAPIエンドポイントへの接続などの高額なコードを実行するとどうなるでしょうか。特にAWSデータベースやAPI Gatewayエンドポイントなどに接続している場合は特に、すべて不要であり、費用とリソースがかかります。その場合は、不要なコードが実行されないようにするために、必ずreturnを使用します。
return
ます。
またはお茶のあなたのカップではないかもしれない可能性のある一般的なイディオムは、組み合わせることであるreturn
とのreject
機能の残りの部分を含むように、同時に機能から約束して終了を拒否し、resolve
実行されません。このスタイルが気に入ったら、コードをもう少しコンパクトにすることができます。
function divide(numerator, denominator) {
return new Promise((resolve, reject) => {
if (denominator === 0) return reject("Cannot divide by 0");
^^^^^^^^^^^^^^
resolve(numerator / denominator);
});
}
約束のコンストラクタは、任意の戻り値を持つ、そしてどのような場合には何もしませんので、これは罰金を作品resolve
とreject
戻り何も。
同じイディオムは、別の回答で示されているコールバックスタイルで使用できます。
function divide(nom, denom, cb){
if(denom === 0) return cb(Error("Cannot divide by zero"));
^^^^^^^^^
cb(null, nom / denom);
}
繰り返しになりますが、呼び出した人divide
は何も返さないと予想し、戻り値に対して何もしないので、これは正常に機能します。
reject
ステータスを返すことに問題はありません
技術的にはここでは必要ありません1 -Promiseは排他的かつ一度だけ解決または拒否できるためです。最初のPromiseの結果が優先され、その後の結果はすべて無視されます。これは、ノードスタイルのコールバックとは異なります。
ことで、あると良いクリーンな練習それ以上の非同期/繰延処理が存在しないので、正確に一つが、この場合には実際に呼び出され、時に実用的、およびされていることを確認します。「早期に戻る」という決定は、機能が完了したときに機能を終了することと、無関係または不要な処理を継続することとの違いはありません。
適切なタイミングで戻る(または条件式を使用して「その他の」ケースの実行を回避する)ことにより、コードが無効な状態で誤って実行されたり、不要な副作用が発生したりする可能性が低くなります。そのため、コードが「予期せず壊れる」可能性が低くなります。
1この技術的な答えは、この場合、「リターン」の後のコードが省略された場合に副作用が発生しないという事実にも依存します。JavaScriptは喜んでゼロで除算し、+ Infinity / -InfinityまたはNaNを返します。
解決/拒否の後で「戻る」ことを行わない場合、停止を意図した後で、ページリダイレクトなどの問題が発生する可能性があります。出典:私はこれに遭遇しました。
Oriの回答はすでに必要ではないことを説明していますreturn
が、それは良い習慣です。promiseコンストラクターはスローセーフであるため、パスで後で渡されるスローされた例外を無視します。基本的に、簡単に確認できない副作用があります。
ことに注意してくださいreturn
早期INGのはコールバックにも非常に一般的です。
function divide(nom, denom, cb){
if(denom === 0){
cb(Error("Cannot divide by zero");
return; // unlike with promises, missing the return here is a mistake
}
cb(null, nom / denom); // this will divide by zero. Since it's a callback.
}
したがって、Promiseでは良い習慣ですが、コールバックでは必須です。コードに関する注意事項:
多くの場合、パラメータを個別に検証して、Promise.reject(reason)で拒否されたpromiseをすぐに返すことができます。
function divide2(numerator, denominator) {
if (denominator === 0) {
return Promise.reject("Cannot divide by 0");
}
return new Promise((resolve, reject) => {
resolve(numerator / denominator);
});
}
divide2(4, 0).then((result) => console.log(result), (error) => console.log(error));