return-await
返されたPromiseのawaitの使用方法を一貫させることを強制します。
このルールによって報告されるいくつかの問題は、 --fix
ESLintコマンドラインオプションによって自動的に修正可能です。.
このルールによって報告されるいくつかの問題は、エディターの修正候補によって手動で修正可能です。 修正候補.
このルールを実行するには 型情報 が必要です。
このルールは、eslint/no-return-await
ルールに基づいて構築されています。特定の場合にオプションで`return await`を要求するサポートを追加するために、基本ルールを拡張しています。
拡張ルールは、`no-return-await`ではなく`return-await`という名前になっています。これは、拡張ルールが肯定と否定の両方を強制できるためです。また、コアルールは現在非推奨となっていますが、拡張ルールは多くのコンテキストで依然として有用です。
- awaitされたPromiseを返すことで、スタックトレース情報が改善されます。
- `return`文が`try...catch`内にある場合、Promiseをawaitすることで、エラーを呼び出し元に任せるのではなく、Promiseの拒否をキャッチすることもできます。
- 一般的な認識とは異なり、`return await promise;`は、Promiseを直接返すのと少なくとも同じくらい高速です。
使用方法
module.exports = {
"rules": {
// Note: you must disable the base rule as it can report incorrect errors
"no-return-await": "off",
"@typescript-eslint/return-await": "error"
}
};
プレイグラウンドでこのルールを試す ↗
オプション
eslint/no-return-await
のオプションを参照してください。
type Options = 'in-try-catch' | 'always' | 'never';
const defaultOptions: Options = 'in-try-catch';
`in-try-catch`
awaitされていないPromiseを返すと予期しないエラー処理制御フローが発生する場合、ルールは`await`を使用する必要があることを強制します。そうでない場合、ルールは`await`を使用*しない*ことを強制します。
エラー処理のケースを網羅的にリストアップする
- `try`内でPromiseを`return`する場合、`catch`または`finally`が常に続くため、`await`する必要があります。
- `catch`内でPromiseを`return`し、`finally`が*ない*場合、`await`しては*いけません*。
- `catch`内でPromiseを`return`し、`finally`が*ある*場合、`await`する*必要*があります。
- `finally`内でPromiseを`return`する場合、`await`しては*いけません*。
- `using`または`await using`宣言とそのスコープの終わりまでの間でPromiseを`return`する場合、`try`ブロックでラップされたコードと同等に動作するため、`await`する必要があります。
- ❌ 間違い
- ✅ 正しい
async function invalidInTryCatch1() {
try {
return Promise.reject('try');
} catch (e) {
// Doesn't execute due to missing await.
}
}
async function invalidInTryCatch2() {
try {
throw new Error('error');
} catch (e) {
// Unnecessary await; rejections here don't impact control flow.
return await Promise.reject('catch');
}
}
// Prints 'starting async work', 'cleanup', 'async work done'.
async function invalidInTryCatch3() {
async function doAsyncWork(): Promise<void> {
console.log('starting async work');
await new Promise(resolve => setTimeout(resolve, 1000));
console.log('async work done');
}
try {
throw new Error('error');
} catch (e) {
// Missing await.
return doAsyncWork();
} finally {
console.log('cleanup');
}
}
async function invalidInTryCatch4() {
try {
throw new Error('error');
} catch (e) {
throw new Error('error2');
} finally {
// Unnecessary await; rejections here don't impact control flow.
return await Promise.reject('finally');
}
}
async function invalidInTryCatch5() {
return await Promise.resolve('try');
}
async function invalidInTryCatch6() {
return await 'value';
}
async function invalidInTryCatch7() {
using x = createDisposable();
return Promise.reject('using in scope');
}
プレイグラウンドで開くasync function validInTryCatch1() {
try {
return await Promise.reject('try');
} catch (e) {
// Executes as expected.
}
}
async function validInTryCatch2() {
try {
throw new Error('error');
} catch (e) {
return Promise.reject('catch');
}
}
// Prints 'starting async work', 'async work done', 'cleanup'.
async function validInTryCatch3() {
async function doAsyncWork(): Promise<void> {
console.log('starting async work');
await new Promise(resolve => setTimeout(resolve, 1000));
console.log('async work done');
}
try {
throw new Error('error');
} catch (e) {
return await doAsyncWork();
} finally {
console.log('cleanup');
}
}
async function validInTryCatch4() {
try {
throw new Error('error');
} catch (e) {
throw new Error('error2');
} finally {
return Promise.reject('finally');
}
}
async function validInTryCatch5() {
return Promise.resolve('try');
}
async function validInTryCatch6() {
return 'value';
}
async function validInTryCatch7() {
using x = createDisposable();
return await Promise.reject('using in scope');
}
プレイグラウンドで開く`always`
返されるすべてのPromiseが`await`されることを要求します。
`always`を使用したコードの例
- ❌ 間違い
- ✅ 正しい
async function invalidAlways1() {
try {
return Promise.resolve('try');
} catch (e) {}
}
async function invalidAlways2() {
return Promise.resolve('try');
}
async function invalidAlways3() {
return await 'value';
}
プレイグラウンドで開くasync function validAlways1() {
try {
return await Promise.resolve('try');
} catch (e) {}
}
async function validAlways2() {
return await Promise.resolve('try');
}
async function validAlways3() {
return 'value';
}
プレイグラウンドで開く`never`
返されるPromiseの`await`をすべて禁止します。
`never`を使用したコードの例
- ❌ 間違い
- ✅ 正しい
async function invalidNever1() {
try {
return await Promise.resolve('try');
} catch (e) {}
}
async function invalidNever2() {
return await Promise.resolve('try');
}
async function invalidNever3() {
return await 'value';
}
プレイグラウンドで開くasync function validNever1() {
try {
return Promise.resolve('try');
} catch (e) {}
}
async function validNever2() {
return Promise.resolve('try');
}
async function validNever3() {
return 'value';
}
プレイグラウンドで開く使用しない場合
型チェックされたLintルールは、従来のLintルールよりも強力ですが、型チェックされたリンティングを設定する必要があります。型チェックルールを有効にした後にパフォーマンスの低下が発生した場合は、パフォーマンストラブルシューティングを参照してください。