禁止使用悬挂的 Promise
要求 Promise 类语句得到适当处理。
在 "plugin:@typescript-eslint/recommended-type-checked"
中扩展 ESLint 配置 可以启用此规则。
此规则报告的一些问题可以通过编辑器 建议 手动修复。
此规则需要 类型信息 才能运行。
“浮动”Promise 是指在没有设置任何代码来处理它可能抛出的任何错误的情况下创建的 Promise。浮动 Promise 会导致一些问题,例如操作顺序不正确、忽略 Promise 拒绝等等。
此规则报告创建但未正确处理的 Promise。处理 Promise 值语句的有效方法包括
await
它return
它void
它- 使用两个参数调用它的
.then()
- 使用一个参数调用它的
.catch()
此规则还报告创建但未正确处理的包含 Promise 的数组。解决此问题的主要方法是使用 Promise 并发方法之一创建一个 Promise,然后根据上述过程处理它。这些方法包括
Promise.all()
Promise.allSettled()
Promise.any()
Promise.race()
no-floating-promises
仅检测未处理的 Promise 语句。有关检测将 Promise 提供给逻辑位置(例如 if 语句)的代码,请参阅 no-misused-promises
。
module.exports = {
"rules": {
"@typescript-eslint/no-floating-promises": "error"
}
};
在游乐场中尝试此规则 ↗
示例
- ❌ 错误
- ✅ 正确
const promise = new Promise((resolve, reject) => resolve('value'));
promise;
async function returnsPromise() {
return 'value';
}
returnsPromise().then(() => {});
Promise.reject('value').catch();
Promise.reject('value').finally();
[1, 2, 3].map(async x => x + 1);
在游乐场中打开const promise = new Promise((resolve, reject) => resolve('value'));
await promise;
async function returnsPromise() {
return 'value';
}
void returnsPromise();
returnsPromise().then(
() => {},
() => {},
);
Promise.reject('value').catch(() => {});
await Promise.reject('value').finally(() => {});
await Promise.all([1, 2, 3].map(async x => x + 1));
在游乐场中打开选项
此规则接受以下选项
type Options = [
{
allowForKnownSafePromises?: (
| {
from: 'file';
name: [string, ...string[]] | string;
path?: string;
}
| {
from: 'lib';
name: [string, ...string[]] | string;
}
| {
from: 'package';
name: [string, ...string[]] | string;
package: string;
}
| string
)[];
/** Whether to ignore async IIFEs (Immediately Invoked Function Expressions). */
ignoreIIFE?: boolean;
/** Whether to ignore `void` expressions. */
ignoreVoid?: boolean;
},
];
const defaultOptions: Options = [
{ ignoreVoid: true, ignoreIIFE: false, allowForKnownSafePromises: [] },
];
ignoreVoid
此选项默认值为 true
,允许您停止规则报告使用 void 运算符消耗的 Promise。这可能是明确标记 Promise 故意不等待的一种好方法。
使用 { ignoreVoid: true }
的此规则的正确代码示例
async function returnsPromise() {
return 'value';
}
void returnsPromise();
void Promise.reject('value');
在游乐场中打开如果将此选项设置为 true
,并且您正在使用 no-void
,则应打开 allowAsStatement
选项。
ignoreIIFE
这允许您跳过对异步 IIFE(立即调用函数表达式)的检查。
使用 { ignoreIIFE: true }
的此规则的正确代码示例
await (async function () {
await res(1);
})();
(async function () {
await res(1);
})();
在游乐场中打开allowForKnownSafePromises
此选项允许将特定类型标记为“安全”以进行浮动。例如,您可能需要在库的 API 返回 Promise 的情况下执行此操作,这些 Promise 的拒绝由库安全处理。
此选项接受一个类型说明符数组,以将其视为安全。数组中的每个项目必须具有以下形式之一
- 在文件中定义的类型(
{ from: "file", name: "Foo", path: "src/foo-file.ts" }
,其中path
是相对于项目根目录的可选路径) - 来自默认库的类型(
{ from: "lib", name: "PromiseLike" }
) - 来自包的类型(
{ from: "package", name: "Foo", package: "foo-lib" }
,这也适用于在类型包中定义的类型)。
使用此规则的代码示例
{
"allowForKnownSafePromises": [
{ "from": "file", "name": "SafePromise" },
{ "from": "lib", "name": "PromiseLike" },
{ "from": "package", "name": "Bar", "package": "bar-lib" }
]
}
- ❌ 错误
- ✅ 正确
let promise: Promise<number> = Promise.resolve(2);
promise;
function returnsPromise(): Promise<number> {
return Promise.resolve(42);
}
returnsPromise();
在游乐场中打开// promises can be marked as safe by using branded types
type SafePromise = Promise<number> & { __linterBrands?: string };
let promise: SafePromise = Promise.resolve(2);
promise;
function returnsSafePromise(): SafePromise {
return Promise.resolve(42);
}
returnsSafePromise();
在游乐场中打开何时不使用它
在大型现有项目中,如果设置了许多浮动 Promise,则可能难以启用此规则。或者,如果您不担心浮动或误用 Promise 导致的崩溃(例如,如果您注册了全局未处理的 Promise 处理程序),那么在某些情况下,可能可以安全地不使用此规则。您可能考虑使用 `void` 和/或 ESLint 禁用注释 来处理这些特定情况,而不是完全禁用此规则。
相关内容
进一步阅读
- "使用 Promise" MDN 文档。特别注意有关 Promise 拒绝事件 和 组合 的部分。
类型检查的 lint 规则比传统的 lint 规则更强大,但也需要配置 类型检查的 lint。如果您在启用类型检查的规则后遇到性能下降,请参阅 性能故障排除。