0

I am not experienced with async functions and I would like to perform a request in a for loop. Here's my code:

app.route('/friendlist').post((req, res) => {
  var body = req.body;
  var list = "";

  con.query(`SELECT * FROM player_friends WHERE main_user_id = '${body.player_id}'`, (err, row, fields) => {
    if (err) throw err;

    async function queryOutUserData(data) {
      var rows = await new Promise((resolve, reject) => {
        con.query(`SELECT * FROM players WHERE player_id = '${data.player_id}'`, (error, player, field) => {
          if (error) {
            console.log(error);
            return reject(error);
          }

          resolve(player);
        });
      });

      rows.then(message => {
        return message
      });
    }

    for (var i = 0; i <= row.length; i++) {
      console.log(row[i].main_user_id);
      var result = await queryOutUserData(row[i]);
      list = list + ";" + result[0].player_id + ":" + result[0].player_username;
    }
    console.log(list);
    return list;
  });
});

Actually here's the full problem: I did some debugging and apparently value i in for loop increases before the promise is resolved. Also as I mentioned I am not familiar with async functions, could you provide me a descriptive resource about how promises and async functions work?

Thanks

NOTE: For better indentation, here's the code: https://hastebin.com/fovayucodi.js

Mike Cluck
  • 31,869
  • 13
  • 80
  • 91
Alper Berber
  • 71
  • 2
  • 10

3 Answers3

0

Instead of using async/await I suggest doing everything in one query using WHERE IN rather than one query per player. See if the following fits your needs:

app.route('/friendlist').post((req,res) => {
    var body = req.body;
    var list = "";

    con.query(`SELECT * FROM player_friends WHERE main_user_id = '${body.player_id}'`, (err, row, fields) => {
      if (err) throw err;

      const playerIds = row.map(player => player.player_id);

      con.query(`SELECT * FROM players WHERE player_id IN ${playerIds}`, (error, players, field) => {
        for (let player of players) {
            list += `;${player.player_id}:${player.player_username}`;
        }
      });

      console.log(list);
      return list;

    });

  });
Matt Aft
  • 8,742
  • 3
  • 24
  • 37
-1

If you await a promise, it evaluates to the result of that promise, so rows is not a promise, it's the result. So this:

 rows.then(message => {return message});

Doesn't make much sense, just do:

 return message;

Also, you have an await inside of a regular function, thats a syntax error.

Additionally return list; doesn't do much (if that is express), you might want to return res.json({ list });.

: I did some debugging and apparently value i in for loop increases before the promise is resolved.

I doubt that you can debug code if you can't actually run it because of the syntax errors.

Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
-1

try to use for-of instead just a for.

something like this:

Async Function:

async function test() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(true);
            return
        }, 1000)
    })
}

Here another function using for and waiting for the finish of loop

async function myFunction() {
    const data = [1,2,3,4,5,6,7,8]

    for(let i of data) {
        const value = await test();
        console.log(value)
    }

    console.log("finish");
}
  • It would benefit the OP and readers of the same level if you could expand your answer to include some explanation as to what is occurring in your answer to make it clear how to use async in loops. It is OK to link out to more details like the async MDN page. – Itanex Oct 18 '19 at 20:11