简体   繁体   English

为什么 ESLint no-await-in-loop 不能与 for await of 一起使用?

[英]Why ESLint no-await-in-loop not working with for await of?

for await of — supposed to be used with asynchronous iterators, it awaits each promise within iterator and handles response of each awaited promise in its body. for await of — 应该与异步迭代器一起使用,它等待迭代器中的每个 promise 并处理其主体中每个等待的 promise 的响应。 From MDN docs this syntax can be used also with sync iterators, so在 MDN 文档中,此语法也可用于同步迭代器,因此

I have the following code examples that work similar:我有以下类似的代码示例:

(async () => {
    const entityIds = [1, 2, 3, 4];
    
    for await (const id of entityIds) {
        console.log(await getEntityById(id));
    }
})();

And:和:

(async () => {
    const entityIds = [1, 2, 3, 4];
    
    for (const id of entityIds) {
        console.log(await getEntityById(id)); // ESLint: Unexpected `await` inside a loop.(no-await-in-loop)
    }
})();

But in the 2nd example I'm getting eslint warning about the rule no-await-in-loop .但是在第二个示例中,我收到了关于规则no-await-in-loop eslint警告。 The question is: why?问题是:为什么? Each iteration of these 2 loops will await for async function completes, but the eslint is not gonna react on 1st case at all.这 2 个循环的每次迭代都将等待异步 function 完成,但eslint根本不会对第一种情况做出反应。

The no-await-in-loop rule in ESLint is supposed to protect you from accidentally processing some data sequentially. ESLint 中的 no-await-in-loop 规则应该可以防止您意外地顺序处理某些数据。 The reasoning is that often having an await in a loop is not intentional because it is more efficient to process the data in parallel.原因是通常在循环中await并不是故意的,因为并行处理数据效率更高。 Thus all usages of await in a loop are considered a "mistake" when the rule is turned on.因此,当规则打开时,循环中所有await的使用都被认为是“错误”。

Using for await...of is explicitly considered "intentional" by the rule.使用for await...of被规则明确认为是“有意的”。 Checking the rule's tests (bottom of the documentation page) the following part is listed as valid code:检查规则的测试(文档页面底部),以下部分被列为有效代码:

valid: [
    // ...

    // Asynchronous iteration intentionally
    "async function foo() { for await (var x of xs) { await f(x) } }"
],

while any usage of await in any other loop construct is invalid.而在任何其他循环结构中使用await都是无效的。 Including using await inside a loop inside a for await...of :包括在for await...of的循环内使用await

invalid: [
    // ...

    // In a nested loop of for-await-of
    { code: "async function foo() { for await (var x of xs) { while (1) await f(x) } }", errors: [error] }
]

The reasoning most likely is that using for await...of you opt into sequential processing.最有可能的原因是使用for await...of你选择进入顺序处理。 If you process an asynchronous iterable, chances are very high that you cannot do that in parallel and it would be an error if you try.如果您处理一个异步可迭代对象,那么您无法并行执行该操作的可能性非常高,如果您尝试这样做将会出错。 If you are processing a synchronous iterable which produces promises there is still a chance that you cannot correctly do this in parallel.如果您正在处理一个产生承诺的同步迭代,您仍然有可能无法正确地并行执行此操作。

ESLint cannot actually detect if you instead have a synchronous iterable which produces synchronous results like an array iterator, therefore, it assumes it is one of the first two options. ESLint 实际上无法检测您是否有一个同步迭代器,它会像数组迭代器一样产生同步结果,因此,它假定它是前两个选项之一。


In my opinion, the rule is flawed as it is all or nothing.在我看来,这条规则是有缺陷的,因为它是全有或全无。 Enabling it means you want no loops with await in them.启用它意味着您不希望其中有await循环。 There are still valid cases where you want sequential processing with for...of and an await inside.在某些有效情况下,您希望在内部使用for...ofawait进行顺序处理。 Which means that your code is likely to be littered with temporary disables of the rule whenever you do not need it.这意味着您的代码很可能会在您不需要时临时禁用该规则

My suggestion is to disable the no-await-in-loop rule and exercise common sense for when you use sequential and when you use parallel processing.我的建议是禁用 no-await-in-loop 规则,并在使用顺序处理和使用并行处理时运用常识。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM