await-thenable
禁止等待非 Thenable 的值.
"Thenable" 值是一个具有 then
方法的对象,例如 Promise。await
关键字 通常用于检索调用 Thenable 的 then
方法的结果。
¥A "Thenable" value is an object which has a then
method, such as a Promise.
The await
keyword is generally used to retrieve the result of calling a Thenable's then
method.
如果 await
关键字用于非 Thenable 的值,则直接解析该值,但仍会暂停执行直到下一个微任务。虽然这样做是有效的 JavaScript,但通常是程序员的错误,例如忘记添加括号来调用返回 Promise 的函数。
¥If the await
keyword is used on a value that is not a Thenable, the value is directly resolved, but will still pause execution until the next microtask.
While doing so is valid JavaScript, it is often a programmer error, such as forgetting to add parenthesis to call a function that returns a Promise.
- Flat Config
- Legacy Config
export default tseslint.config({
rules: {
"@typescript-eslint/await-thenable": "error"
}
});
module.exports = {
"rules": {
"@typescript-eslint/await-thenable": "error"
}
};
在线运行试试这个规则 ↗
示例
¥Examples
- ❌ 错误
- ✅ 正确
await 'value';
const createValue = () => 'value';
await createValue();
Open in Playgroundawait Promise.resolve('value');
const createValue = async () => 'value';
await createValue();
Open in Playground异步迭代(for await...of
循 环)
¥Async Iteration (for await...of
Loops)
此规则还检查 for await...of
语句,并报告正在迭代的值是否不可异步迭代。
¥This rule also inspects for await...of
statements, and reports if the value being iterated over is not async-iterable.
:::infofor await...of
loops used on an array of Promises?][为什么规则报告
虽然 for await...of
可以与同步可迭代对象一起使用,并且它将等待可迭代对象产生的每个 promise,但不建议这样做。你可能需要考虑一些细微差别。
¥While for await...of
can be used with synchronous iterables, and it will await each promise produced by the iterable, it is inadvisable to do so.
There are some tiny nuances that you may want to consider.
使用 for await...of
和使用 for...of
之间的最大区别(除了自己等待每个结果)是错误处理。当循环体内发生错误时,for await...of
不会关闭原始同步可迭代对象,而 for...of
会关闭。有关详细示例,请参阅 关于将 for await...of
与 sync-iterables 结合使用的 MDN 文档。
¥The biggest difference between using for await...of
and using for...of
(apart from awaiting each result yourself) is error handling.
When an error occurs within the loop body, for await...of
does not close the original sync iterable, while for...of
does.
For detailed examples of this, see the MDN documentation on using for await...of
with sync-iterables.
还要考虑是否需要顺序等待。使用 for await...of
可能会掩盖并发处理的潜在机会,例如 no-await-in-loop
报告的机会。考虑改用 promise 并发方法 之一以获得更好的性能。
¥Also consider whether you need sequential awaiting at all. Using for await...of
may obscure potential opportunities for concurrent processing, such as those reported by no-await-in-loop
. Consider instead using one of the promise concurrency methods for better performance.
:::
示例
¥Examples
- ❌ 错误
- ✅ 正确
async function syncIterable() {
const arrayOfValues = [1, 2, 3];
for await (const value of arrayOfValues) {
console.log(value);
}
}
async function syncIterableOfPromises() {
const arrayOfPromises = [
Promise.resolve(1),
Promise.resolve(2),
Promise.resolve(3),
];
for await (const promisedValue of arrayOfPromises) {
console.log(promisedValue);
}
}
Open in Playgroundasync function syncIterable() {
const arrayOfValues = [1, 2, 3];
for (const value of arrayOfValues) {
console.log(value);
}
}
async function syncIterableOfPromises() {
const arrayOfPromises = [
Promise.resolve(1),
Promise.resolve(2),
Promise.resolve(3),
];
for (const promisedValue of await Promise.all(arrayOfPromises)) {
console.log(promisedValue);
}
}
async function validUseOfForAwaitOnAsyncIterable() {
async function* yieldThingsAsynchronously() {
yield 1;
await new Promise(resolve => setTimeout(resolve, 1000));
yield 2;
}
for await (const promisedValue of yieldThingsAsynchronously()) {
console.log(promisedValue);
}
}
Open in Playground显式资源管理 (await using
语句)
¥Explicit Resource Management (await using
Statements)
此规则还检查 await using
语句。如果正在使用的 disposable 不是异步可处理的,则不需要 await using
语句。
¥This rule also inspects await using
statements.
If the disposable being used is not async-disposable, an await using
statement is unnecessary.
示例
¥Examples
- ❌ 错误
- ✅ 正确
function makeSyncDisposable(): Disposable {
return {
[Symbol.dispose](): void {
// Dispose of the resource
},
};
}
async function shouldNotAwait() {
await using resource = makeSyncDisposable();
}
Open in Playgroundfunction makeSyncDisposable(): Disposable {
return {
[Symbol.dispose](): void {
// Dispose of the resource
},
};
}
async function shouldNotAwait() {
using resource = makeSyncDisposable();
}
function makeAsyncDisposable(): AsyncDisposable {
return {
async [Symbol.asyncDispose](): Promise<void> {
// Dispose of the resource asynchronously
},
};
}
async function shouldAwait() {
await using resource = makeAsyncDisposable();
}
Open in Playground选项
该规则不可配置。
何时不使用它
¥When Not To Use It
如果你想要允许代码 await
非 Promise 值。例如,如果你的框架正在从一种异步代码样式过渡到另一种样式,则不必要地包含 await
可能会很有用。这通常不是首选,但有时对于视觉一致性很有用。你可以考虑在这些特定情况下使用 ESLint 禁用注释,而不是完全禁用此规则。
¥If you want to allow code to await
non-Promise values.
For example, if your framework is in transition from one style of asynchronous code to another, it may be useful to include await
s unnecessarily.
This is generally not preferred but can sometimes be useful for visual consistency.
You might consider using ESLint disable comments for those specific situations instead of completely disabling this rule.
Type checked lint rules are more powerful than traditional lint rules, but also require configuring type checked linting.
See Troubleshooting > Linting with Type Information > Performance if you experience performance degradations after enabling type checked rules.