【问题标题】:Alternative to looping inside for ... of and while(true)替代循环内部 for ... of 和 while(true)
【发布时间】:2019-02-02 06:52:54
【问题描述】:

我通常会在其中编写带有awaits 的循环,以便按顺序执行某些任务或在迭代之间实现一定的间隔。

例如:

for (const item of items) {
  await doSomthing(item);
}

或:

while(true) {
  await doSomeTask();
  await delay(60000);  
}

然而,ESLint 正在斥责我写这种代码。

当我不想同时运行所有异步任务而是想以慢速运行它们时,什么是带有等待的顺序循环和内部带有等待的无限循环的替代模式?

【问题讨论】:

  • for/in 是用来迭代对象的,不应该在其他场景中使用。
  • @ScottMarcus 道歉,我的意思是......固定
  • 您需要更充分地使用Promises 而不仅仅是使用await 关键字。
  • @ScottMarcus await 涉及 Promises tho
  • ESLint 到底是怎么说的?如果这是您想要做的,我看不出该代码有什么严重错误。

标签: javascript ecmascript-6 async-await eslint-config-airbnb


【解决方案1】:

ESLint 责备我写这种代码。

这里的解决方案是禁用 ESLint - 单独禁用这些行,或者一般情况下禁用 that horrible rule。甚至规则文档自己也说“在许多情况下 [...] 在循环中使用 await 是有意义的,建议通过标准 ESLint 禁用注释禁用规则”。

您正在编写的代码非常适合按顺序执行任务。如果你想避免它,只有递归作为 linter 无法检测到的替代方案:-)

【讨论】:

  • 我不会称之为“可怕的规则”。它只是指出一些没有充分利用 async/await 功能的代码。你是正确的,当某些语句应该顺序执行时,上面的代码是完全有效的,但是,如果没有必要,那么你应该使用 Promise.all() 来提高效率/速度。
  • @TimKlein 我认为默认情况下将其设为错误是很可怕的。对我来说,误报率也太高了,但也许只有我已经知道何时使用哪个。当您觉得它“谴责”您而不是提供有用的建议时,linter 就没有用了。
  • @TimKlein 串联运行当然并不总是一件坏事。我对Promise.all 的最大问题是它没有内置节流功能,带有并发选项的 Bluebirds map 确实应该是 Promise.all 的样子。
【解决方案2】:

您可以使用递归函数来实现相同的效果,这使您可以更充分地利用您正在做的事情的异步特性。您的主线程可以继续执行其他操作,而不是等待 for 循环结束 - 任何依赖该部分完成的代码都可以在您传入的回调函数中执行。

function asynchronousFunction(thing){
  //do something
  console.log('doing something')
  return new Promise(resolve => {
    setTimeout(e => resolve(), 1000)
  })
}

async function doSomething(arrayOfThings, next){
  const thing = arrayOfThings.pop()
  const responseFromAsyncFunction = await asynchronousFunction(thing)
  console.log('after', arrayOfThings.length)
  if(arrayOfThings.length) doSomething(arrayOfThings, next)
  else next()
}

const myData = [1,2,3,4,5]

doSomething(myData.slice(0), function(){ console.log('done') })

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-10
    • 1970-01-01
    • 1970-01-01
    • 2021-06-29
    • 2018-11-05
    • 1970-01-01
    • 2013-06-07
    • 2021-07-27
    相关资源
    最近更新 更多