【问题标题】:no-await-in-loop, advice about alternative solutionno-await-in-loop,关于替代解决方案的建议
【发布时间】:2020-01-20 12:34:50
【问题描述】:

我在我的应用程序中使用 Express 和 mongoose,并且我正在使用 ESLint。我的应用中有:

  • 一些类别,由名称、id 和一些外部类别的 id 定义以匹配

  • 一些事件,由名称和类别定义

我正在做这样的事情来获取类别,同时从 json 创建事件:

let promises = [];
for (let i = 0; i < events.length; i++) {
   const event = new Event({
      name: events[i].name,
      category: await Category.findOne({externalSource: events[I].category_id})
   });
   promises.push(event.save());
}
Promise.all(promises)...

我的代码正在运行,但 ESLint 抛出错误 no-await-in-loop。我用/* eslint-disable no-await-in-loop */ 停用了它,但我想知道在尊重 ESLint 约束的同时我必须这样做的好的替代解决方案是什么?

我正在考虑在 mongoose 中使用预保存钩子来设置类别(如果尚未定义),但我不知道这是否是一种好习惯,我认为它可能会产生一些副作用

谢谢

【问题讨论】:

    标签: express asynchronous mongoose eslint


    【解决方案1】:

    await 在循环中将不允许每个操作并行执行(几乎)。仅当您希望上一个操作在循环中的下一个操作之前完成时才应该使用它。

    话虽这么说,await 会等到它得到当前请求的响应后再进行下一个操作。而您可以使用计数器变量并行或一个接一个地触发操作应该足以解决您的问题:

    let tasks = [];
    var counter = 0
    for (let i = 0; i < events.length; i++) {
      Category.findOne({externalSource: events[i].category_id}).then(d => {
        counter++
        tasks.push(new Event({
          name: events[i].name,
          category: d
        }).save())
        if(counter === events.length){
          Promise.all(tasks).then(allData => {
            console.log('Done', allData)
          }).catch(console.error)
        }
      }).catch(console.error)
    }
    

    【讨论】:

    • 谢谢,我不太喜欢这种方法,因为我认为它使代码更难阅读,但它在性能方面似乎是一个很好的解决方案,我会换成类似的那
    猜你喜欢
    • 1970-01-01
    • 2019-02-08
    • 1970-01-01
    • 1970-01-01
    • 2011-04-13
    • 2016-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多