Ashvin Sharma
Ashvin Sharma

Reputation: 583

Use Promise.all instead of async/await if a forEach

I am making a discord bot using discord.js which gets data from an API and add or delete the message associated with the data.

In the snippet below I have written the logic to delete the messages if the corresponding data is no longer available at API.

gameEmbeds is a map which contains key as the identifier for the data from API and val as the identifier for the message in the discord channel.

  gameEmbeds.forEach(async (val, key, map) => {
  if (map !== undefined && newGames.get(key) === undefined) {
    const message = await channel.fetchMessage(val);
    message.delete()
      .catch((e) => {
        console.error(`${new Date()} `, e);
      });
  }

I have to make iterator function async because every entry to be processed one by one to make the changes in the UI look smoother which violates the async nature of JS.

I think I can make sure this happens with Promise.all which will also make this code a bit faster, however, I don't know how to implement it in my code without breaking stuff. I am new to node.js. Please help.

EDIT: Thanks CF256, I removed redundant .then()

Upvotes: 0

Views: 1675

Answers (1)

Felix Fong
Felix Fong

Reputation: 985

I will create a new array for holding all the small promises, and once the forEach loop is complete, I will then call the Promise.all on the small promises keeper

const allDeleteJobs = [];
gameEmbeds.forEach(async (val, key, map) => {
  if (map !== undefined && newGames.get(key) === undefined) {
    const message = await channel.fetchMessage(val);
    // Push the new delete job to the array registry
    allDeleteJobs.push(message.delete());
  }
});
(async () => {
  if(allDeleteJobs.length >= 1){
    await Promise.all(allDeleteJobs);
    // Delete all the messages or do other stuff
  }
})()
.catch(error => console.error(error));

Upvotes: 1

Related Questions