返回 await
强制一致地等待返回的 Promise。
此规则建立在 eslint/no-return-await
规则之上。它扩展了基本规则,以在某些情况下添加对可选要求 return await
的支持。
扩展规则名为 return-await
而不是 no-return-await
,因为扩展规则可以强制执行正向或负向。此外,虽然核心规则现在已弃用,但扩展规则在许多情况下仍然有用。
- 返回一个等待的 Promise 可以改善堆栈跟踪信息。
- 当
return
语句位于try...catch
中时,等待 Promise 还可以捕获 Promise 的拒绝,而不是将错误留给调用者。 - 与普遍看法相反,
return await promise;
至少与直接返回 Promise 一样快。
如何使用
.eslintrc.cjs
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"
}
};
在游乐场中尝试此规则 ↗
选项
type Options = 'in-try-catch' | 'always' | 'never';
const defaultOptions: Options = 'in-try-catch';
in-try-catch
在返回未等待的 Promise 会导致意外的错误处理控制流的情况下,该规则强制执行必须使用 await
。否则,该规则强制执行必须不使用 await
。
详尽列出错误处理情况
- 如果你在
try
中return
一个 Promise,那么它必须被await
,因为它总是会紧随其后的是catch
或finally
。 - 如果你在
catch
中return
一个 Promise,并且没有finally
,那么它不应该被await
。 - 如果你在
catch
中return
一个 Promise,并且有finally
,那么它必须被await
。 - 如果你在
finally
中return
一个 Promise,那么它不应该被await
。 - 如果你在
using
或await using
声明与其作用域结束之间return
一个 Promise,那么它必须被await
,因为它与包装在try
块中的代码行为相同。
- ❌ 错误
- ✅ 正确
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 规则更强大,但也需要配置 类型检查的 lint。如果您在启用类型检查的规则后遇到性能下降,请查看 性能故障排除。