Неожиданный "ожидание" внутри цикла. (Не-Await-в-петле)

Как я должен ждать 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)

Ответы

Ответ 1

Если вам нужно отправлять каждое сообщение по одному, то у вас все в порядке, и в соответствии с документами, вы можете просто проигнорировать ошибку 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);
});

Ответ 2

Выполнение await внутри циклов можно избежать, если итерации не имеют зависимости в большинстве случаев, поэтому eslint предупреждает об этом здесь

Вы можете переписать свой код как:

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);
    }
  });

Если вы все еще и отправляете сообщения "один за другим", ваш код в порядке, но eslint вы продолжаете бросать эту ошибку

Ответ 3

Еще одно изменение, использующее Object.entries.

const promise = query.exec();
promise.then(async(doc) => {
    const pending = [];

    for (const [idx, {text}] of Object.entries(doc)) {
      pending.push(
        bot.sendMessage(msg.chat.id, '💬 ${idx + 1} and ${text}', opts)
      );
    }

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