70

How Should I await for bot.sendMessage() inside of loop?
Maybe I Need await Promise.all But I Don't Know How Should I add to bot.sendMessage()

Code:

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

Error:

[eslint] Unexpected `await` inside a loop. (no-await-in-loop)
Kaspar Lee
  • 5,446
  • 4
  • 31
  • 54
Saeed Heidarizarei
  • 8,406
  • 21
  • 60
  • 103

4 Answers4

107

If you need to send each message one-at-a-time, then what you have is fine, and according to the docs, you can just ignore the eslint error like this:

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

However, if there is no required order for sending the messages, you should do this instead to maximize performance and throughput:

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);
});
Patrick Roberts
  • 49,224
  • 10
  • 102
  • 153
  • I want to use this code to get user messages and Show those Messages to them, Is this way fit to my question? – Saeed Heidarizarei Feb 23 '18 at 22:45
  • 1
    @SedricHeidarizarei The first block will silence the eslint error you were getting. The second one is not functionally equivalent, but if it works for you, then that's probably preferable since it's more efficient. – Patrick Roberts Feb 23 '18 at 22:53
11

Performing await inside loops can be avoided once iterations doesn't have dependency in most cases, that's why eslint is warning it here

You can rewrite your code as:

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

If you still and to send one-after-one messages, your code is ok but eslint you keep throwing this error

guijob
  • 4,413
  • 3
  • 20
  • 39
2

I had a similar issue recently, I was getting lintting errors when trying to run an array of functions in a chain as apposed to asynchronously.

and this worked for me...

const myChainFunction = async (myArrayOfFunctions) => {
  let result = Promise.resolve()
  myArrayOfFunctions.forEach((myFunct) => {
    result = result.then(() => myFunct()
  })
  return result
}
Carlene
  • 357
  • 2
  • 12
2

I am facing the same issue when I used await inside forEach loop. But I tried with recursive function call to iterate array.

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);
};  
Peter Csala
  • 17,736
  • 16
  • 35
  • 75
Umang Patel
  • 21
  • 1
  • 2
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jan 13 '22 at 08:34
  • This does not really answer the question. If you have a different question, you can ask it by clicking [Ask Question](https://stackoverflow.com/questions/ask). To get notified when this question gets new answers, you can [follow this question](https://meta.stackexchange.com/q/345661). Once you have enough [reputation](https://stackoverflow.com/help/whats-reputation), you can also [add a bounty](https://stackoverflow.com/help/privileges/set-bounties) to draw more attention to this question. - [From Review](/review/late-answers/30806718) – mswgen Jan 17 '22 at 05:22