8

I have an array of users and I want to check how many of them are joined to my telegram channel and my checking method is an async method and I can use the method like this:

check(user)
    .then((res) => {
    if(res) {
       // user is joined 
      }
    else {
       // user is not joined
    }
})

But I don't know how to use this method for an array of users.

I have tested this code :

members = 0;
users.forEach((user) => {
            check(user)
                .then((result) => {
                    if(result) {
                          members++;
                      }
                });
        })

But this code is definitely wrong because I don't know when should I send the result to my admin (the person who want to check how many users are joined). I put the sending method after the forEach but It shows a very low number(near 0).

I searched and I found a keyword await and I tried it in an async method:

async function checkMembership() {
    let data;
    await check(user)
        .then((res) => {
            data = res
        });
    console.log(data);
}

and It works well but when I use the await in forEach loop like this:

users.forEach((user) => {
            await check(user)
                .then((result) => {
                    console.log(result);
                });
        })

I got the following error: SyntaxError: await is only valid in async function. How should I handle this magical forEach loop?

UPDATE-1: I have tested this code too but I got the previous error:

async function checkMembership() {

    User.find({}, (err, res) => {
        for(let user of res) {
            await check(user)
                .then((ress) => {
                console.log(ress)
                })
        }
        console.log('for is finished');
  });
}

UPDATE-2:

This code didn't work too:

Promise.all(users.map(check))
            .then((Res) => {
                console.log(Res);
            })

and I got the following error:

TypeError: #<Promise> is not a function

Sunderam Dubey
  • 1
  • 11
  • 20
  • 40
Leo
  • 867
  • 1
  • 15
  • 41
  • 2
    Possible duplicate of [Using async/await with a forEach loop](https://stackoverflow.com/questions/37576685/using-async-await-with-a-foreach-loop) – Josh Lee Feb 21 '18 at 14:28

2 Answers2

11

For using await keyword you need to define the function with async keyword, e.g.

users.forEach(async (user) => {
  await check(user)
    .then((result) => {
      console.log(result);
    });
  })

However this code is most likely not the thing you want as it is going to fire async calls without waiting for them to finish (Using async/await with a forEach loop)

To make it properly you can use Promise.all, e.g.

Promise.all(users.map(check)).then((results) => {
  //results is array of all promise results, in your case it should be
  // smth like [res, false|null|undefined, res, ...]
})
Sergii Vorobei
  • 1,477
  • 13
  • 19
0

You could use the async library which has a built-in forEach, then process the result in the callback. Great tutorial here

Edit - Here is the example form Sebastian Eilund:

async.forEach(users, function(user, callback) {
  //do stuff
  callback();
}, function (err) {
  //finished doing stuff for all users
});
daanp
  • 9
  • 4