【问题标题】:Retry asynchronous operations that were unsuccessfull - How to avoid await inside of loops (no-await-in-loop) in EsLint?重试不成功的异步操作 - 如何避免在 EsLint 中的循环内等待(无等待循环)?
【发布时间】:2020-08-09 10:40:58
【问题描述】:

我有一系列来自 JSON 的游览,并将它们全部导入数据库。

我使用 for-loop 是因为我想将所有错误导览提取到另一个文件中,以便我可以修复它并稍后再次重新导入。

这是我的代码,它按预期工作。


const importData = async () => {


  const tours = JSON.parse(
    await fs.readFile(path.join(__dirname, 'data', 'final.json'), 'utf8')
  );
 

  const errorTours = [];


  for (let i = 0; i < tours.length; i += 1) {

   const tour = tours[parseInt(i, 10)];

     try {
       await Tour.create(tour);
     } catch (e) {
       errorTours.push({ tour, error: e });
     }
  }


  await fs.writeFile('errorTour.json', JSON.stringify(errorTours));

  console.log('finished!!! :tada:');
}

但我得到了"Disallow await inside of loops (no-await-in-loop)" EsLint Error.

对可迭代对象的每个元素执行操作是一项常见任务。但是,将 await 作为每个操作的一部分执行表明程序没有充分利用 async/await 的并行化优势。

通常,应重构代码以一次创建所有 Promise,然后使用 Promise.all() 访问结果。否则,每个后续操作将在前一个操作完成之前不会开始。

也许就我而言,the Promise.allSettled() 更适合,对吧?

我是 JS 新手,对如何将我的异步等待代码更改为 Promise 代码以使用 Promise.allSettled 感到非常困惑。

或者有没有更好的方法来重试不成功的异步操作?

你们能告诉我在这种情况下的方向吗?

谢谢,

【问题讨论】:

  • 你能把你的promise推送到一个数组然后返回promise.all([promises])吗?
  • 你为什么打电话给parseInt(i,10)i 已经是一个整数,因为您刚刚声明并自己分配了它。
  • @ThinhNV - 在这种情况下,这是一个虚假的警告,导致您添加了不必要的代码。见security.stackexchange.com/questions/170648/…。由于i 直接来自您这里的代码,因此完全没有注入风险。
  • 您必须了解警告的含义以及它是否真的适合您的代码。如果没有,那么您可以关闭该特定警告或插入一条注释,告诉它在这部分代码中忽略该警告。在不了解警告的实际含义以及它们是否确实相关的情况下,您不能/不应该使用这些工具。

标签: javascript node.js mongodb asynchronous async-await


【解决方案1】:

这个怎么样?

 const TourPromises = tours.map(tour => Tour
    .create(tour)
    .catch(e => errorTours.push({tour, error: e}))
  )
 await Promise.all(TourPromises);

祝你好运……

【讨论】:

  • @ThinhNV - 您知道,这与您的原始代码不完全相同。这将并行运行所有异步操作。您的原始代码按顺序运行它们(一个接一个)。并行可能会更快地获得结果,但如果您的数组更大,则可能会因同时运行的请求过多而导致问题(例如目标主机的速率限制或更大的内存使用量)。
【解决方案2】:

这是我的尝试,感谢@Atlante Avila 和Eslint docs

  const TourPromises = [];
  for (let i = 0; i < tours.length; i += 1) {
    const tour = tours[parseInt(i, 10)];

    TourPromises.push(
      Tour.create(tour).catch((e) => {
        errorTours.push({ tour, error: e });
      })
    );
  }

  await Promise.all(TourPromises);

旧代码:耗时 5466.025282999966 毫秒。

新代码:耗时 1682.5688519999385 毫秒。

看起来好多了,

【讨论】:

    猜你喜欢
    • 2021-06-21
    • 1970-01-01
    • 1970-01-01
    • 2020-08-02
    • 2018-08-04
    • 2017-12-12
    • 1970-01-01
    • 2023-01-20
    • 1970-01-01
    相关资源
    最近更新 更多