Rickie Cheng
Rickie Cheng

Reputation: 11

For-each loop in await all runs simultaneously. What loop to use?

first time making a discord bot (discord.js) and stuck in a situation in which my awaitMessage function all runs simultaneously. For example, when I call the command, it does this in a for each loop of 5.

What is this item? You have 60 seconds!

What is this item? You have 60 seconds!

What is this item? You have 60 seconds!

What is this item? You have 60 seconds!

What is this item? You have 60 seconds!

I looked on stackoverflow and I saw a thread that using a for-of loop in await functions can potentially fix this situation, but I don't know how it can apply to my code. Thanks

  var i;
    for(i = 0; i < 5; i++){
        var random = Math.floor((Math.random() * etcList.length));
        message.channel.send("What is this item? You have 60 seconds!", {files: ["./pictures/images/img"+(random+1)+".jpg"]});

        const filter = m => m.content == (etcList[random].toString()) || (m.content==("skip"));
        message.channel.awaitMessages(filter, {max:1, time:60000})
        .then(collected => {
            if(collected.first().content == ("skip")){
                return message.channel.send("This question has been skipped! The answer was: " + etcList[random].toString());
            }
            if(collected.first().content == (etcList[random].toString())){
                message.channel.send(collected.first().author + " has won! The answer was: " + etcList[random].toString());
            }

        })
        .catch(err => {
            message.channel.send("Time is up! The answer was: " + etcList[random].toString());
        })
    }

Upvotes: 1

Views: 647

Answers (2)

Aritra Chakraborty
Aritra Chakraborty

Reputation: 12552

Without refactoring the code you can just add await before your promises and wrap it using an async function.

Here is an Minimal, Complete, and Verifiable example:

async function func() {
    var i;
    for (i = 0; i < 5; i++) {
        await new Promise((res, rej) => {
            setTimeout(() => { console.log('x=>'); res() }, 1000)
        })
        .then(() => console.log('y'));
    }
}

Hope this clarifies(or confuses) some things!

Upvotes: 0

Kamil Kiełczewski
Kamil Kiełczewski

Reputation: 92587

Instead of message.channel.awaitMessages(...).then(...).catch(...) use this in for-loop

  try {
    let collected = await message.channel.awaitMessages(filter, {
      max: 1,
      time: 60000
    });

    if (collected.first().content == ("skip")) {
        return message.channel.send("This question has been skipped! The answer was: " + etcList[random].toString());
    }

    if (collected.first().content == (etcList[random].toString())) {
        message.channel.send(collected.first().author + " has won! The answer was: " + etcList[random].toString());
    }
  } catch (e) {    
    message.channel.send("Time is up! The answer was: " + etcList[random].toString());
  }

We use await key word here which will 'wait' for function result. You for-loop shoud be placed in function which use async keyword on its definition

Upvotes: 1

Related Questions