【问题标题】:Unexpected `await` inside a loop. (no-await-in-loop)循环内出现意外的“等待”。 (无等待循环)
【发布时间】:2018-08-04 01:13:40
【问题描述】:

我应该如何在循环内等待bot.sendMessage()?
也许我需要await Promise.all 但我不知道我应该如何添加到bot.sendMessage()

代码:

const promise = query.exec();
promise.then(async (doc) => {
    let count = 0;
    for (const val of Object.values(doc)) {
        ++count;
        await bot.sendMessage(msg.chat.id, `???? ${count} and ${val.text}`, opts);
    }
}).catch((err) => {
    if (err) {
        console.log(err);
    }
});

错误:

[eslint] Unexpected `await` inside a loop. (no-await-in-loop)

【问题讨论】:

  • 消息需要一次发送还是一次性发送?
  • 使用此代码,我在 2 之后有消息 1 并且...但消息没有排序
  • 您还没有回答问题。 Which do you want?
  • 我看不懂,但是我想按顺序发送消息
  • 你为什么不使用promise.all?喜欢await Promise.all(Object.values(doc).map((val, idx) => bot.sendMessage(msg.chat.id, `???? ${idx} and ${val.text}`, opts);)

标签: javascript async-await


【解决方案1】:

如果您需要一次发送一条消息,那么您所拥有的就可以了,according to the docs,您可以像这样忽略 eslint 错误:

const promise = query.exec();
promise.then(async doc => {
  /* eslint-disable no-await-in-loop */
  for (const [index, val] of Object.values(doc).entries()) {
    const count = index + 1;
    await bot.sendMessage(msg.chat.id, `? ${count} and ${val.text}`, opts);
  }
  /* eslint-enable no-await-in-loop */
}).catch(err => {
  console.log(err);
});

但是,如果发送消息没有要求的顺序,您应该改为这样做以最大限度地提高性能和吞吐量:

const promise = query.exec();
promise.then(async doc => {
  const promises = Object.values(doc).map((val, index) => {
    const count = index + 1;
    return bot.sendMessage(msg.chat.id, `? ${count} and ${val.text}`, opts);
  });

  await Promise.all(promises);
}).catch(err => {
  console.log(err);
});

【讨论】:

  • 我想使用此代码获取用户消息并向他们显示这些消息,这种方式适合我的问题吗?
  • @SedricHeidarizarei 第一个块将使您收到的 eslint 错误静音。第二个在功能上并不等同,但如果它对你有用,那么它可能更可取,因为它更有效。
【解决方案2】:

在大多数情况下,一旦迭代没有依赖关系,就可以避免在循环内执行 await,这就是为什么 eslint 会警告它 here

您可以将代码重写为:

const promise = query.exec();
  promise.then(async (doc) => {
    await Promise.all(Object.values(doc).map((val, idx) => bot.sendMessage(msg.chat.id, `? ${idx + 1} and ${val.text}`, opts);)
  }).catch((err) => {
    if (err) {
      console.log(err);
    }
  });

如果你仍然发送一个接一个的消息,你的代码是好的,但是你一直抛出这个错误

【讨论】:

    【解决方案3】:

    我最近遇到了类似的问题,我在尝试以异步方式运行链中的一组函数时遇到了 linting 错误。

    这对我有用...

    const myChainFunction = async (myArrayOfFunctions) => {
      let result = Promise.resolve()
      myArrayOfFunctions.forEach((myFunct) => {
        result = result.then(() => myFunct()
      })
      return result
    }

    【讨论】:

      【解决方案4】:

      当我在 forEach 循环中使用 await 时,我遇到了同样的问题。但我尝试使用递归函数调用来迭代数组。

      const putDelay = (ms) =>
          new Promise((resolve) => {
              setTimeout(resolve, ms);
          });
      
      const myRecursiveFunction = async (events, index) => {
          if (index < 0) {
              return;
          }
          callAnotherFunction(events[index].activity, events[index].action, events[index].actionData);
          await putDelay(1);
          myRecursiveFunction(events, index - 1);
      };  
      

      【讨论】:

      • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。
      • 这并不能真正回答问题。如果您有其他问题,可以点击 提问。要在此问题有新答案时收到通知,您可以follow this question。一旦你有足够的reputation,你也可以add a bounty 来引起对这个问题的更多关注。 - From Review
      猜你喜欢
      • 2023-01-20
      • 2017-08-17
      • 1970-01-01
      • 2015-07-18
      • 2020-05-09
      • 1970-01-01
      • 2022-12-08
      • 2015-03-13
      • 2017-12-16
      相关资源
      最近更新 更多