-2

Hey i want to my bot send a message when the foreach is finished with the duration

code:


        let beforecheck = new Date();


        bot.guilds.forEach(guild => {

            //my foreach code

            }).then(() => {

            let aftercheck = new Date();

            var finished = new Discord.RichEmbed()
            .setDescription("✔ Finished ✔")
            .addField(" Bot Latency", bot.ping + " ms")
            .addField("expected time", expectedtime + " minute(s)")
            .addField("final time", (60000 / (beforecheck - aftercheck)) + " minute(s)")

            message.channel.send(finished)

            })

thanks for any response

HiiZun
  • 27
  • 6
  • Does this answer your question? [Using async/await with a forEach loop](https://stackoverflow.com/questions/37576685/using-async-await-with-a-foreach-loop) – Klaycon Dec 23 '19 at 20:39
  • In short: Use `for..of` instead. – Klaycon Dec 23 '19 at 20:40
  • `forEach` is synchronous... – Heretic Monkey Dec 23 '19 at 20:40
  • @Klaycon I don't know how to do too much. i'm beginner – HiiZun Dec 23 '19 at 20:45
  • @HereticMonkey From the code snippet and context it seems like some asynchronous operation will be done in the `forEach` that the asker needs all the `finished` code to run only after it's all done. Common problem - answer is to not use `forEach` as it does not lend itself to such issues. – Klaycon Dec 23 '19 at 20:47
  • @Klaycon That's certainly an assumption that could be made. I prefer to have OPs update their questions to make them clear so that there are no ambiguities. – Heretic Monkey Dec 23 '19 at 20:50
  • what do i do please ? – HiiZun Dec 23 '19 at 20:51
  • @HiiZun it would be best if you edit your question and add in what you plan to do in the forEach – Klaycon Dec 23 '19 at 20:55

1 Answers1

1

From your code it seems like you expect the forEach to take a significant amount of time, and from the fact that you're iterating over guilds I expect that involves some sort of asynchronous Discord API calls. If those are both true, forEach is the wrong tool for the job.

If order matters: (in an async function)

    let beforecheck = new Date();

    for(const guild of bot.guilds) { //might need bot.guilds.array()
        //use await on asynchronous calls
    }

    let aftercheck = new Date();

    var finished = new Discord.RichEmbed()
        .setDescription("✔ Finished ✔")
        .addField(" Bot Latency", bot.ping + " ms")
        .addField("expected time", expectedtime + " minute(s)")
        .addField("final time", (60000 / (beforecheck - aftercheck)) + " minute(s)")

    message.channel.send(finished)

If order doesn't matter:

    let beforecheck = new Date();

    await Promise.all(bot.guilds.map(guild => {
        //return a promise or use async/await here
    }); //can also use .then() here but async/await is better

    let aftercheck = new Date();

    var finished = new Discord.RichEmbed()
        .setDescription("✔ Finished ✔")
        .addField(" Bot Latency", bot.ping + " ms")
        .addField("expected time", expectedtime + " minute(s)")
        .addField("final time", (60000 / (beforecheck - aftercheck)) + " minute(s)")

    message.channel.send(finished)
Klaycon
  • 10,599
  • 18
  • 35
  • okay where i must put the await because when i put it on the channel.send the bot don't reply to messages – HiiZun Jan 17 '20 at 20:03
  • you put the await where i wrote in the answer, if you are having issues with your implementation, please edit the question or ask a new one so we can see the problematic code – Klaycon Jan 17 '20 at 20:08
  • @HiiZun this code uses `setInterval` which will do something *repeatedly* every `interval` ms, so, every 15 seconds from running this code forever you send a message to every guild – Klaycon Jan 17 '20 at 20:14
  • use `setTimeout` instead - and if you want to wait for all `setTimeout` to run, you need to wrap it in a Promise – Klaycon Jan 17 '20 at 20:15