Асинхронные функции для циклов JavaScript - PullRequest
0 голосов
/ 18 октября 2019

У меня нет опыта работы с асинхронными функциями, и я хотел бы выполнить запрос в цикле for. Вот мой код:

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;
  });
});

Собственно, вот и вся проблема: я выполнил некоторую отладку и, по-видимому, значение i в цикле for увеличивается до того, как обещание будет разрешено. Кроме того, как я уже упоминал, я не знаком с асинхронными функциями. Не могли бы вы предоставить описательный ресурс о том, как работают обещания и асинхронные функции?

Спасибо

ПРИМЕЧАНИЕ. Для лучшего отступа вот код:https://hastebin.com/fovayucodi.js

Ответы [ 3 ]

0 голосов
/ 18 октября 2019

попробуйте использовать for-of вместо просто for.

как-то так:

Асинхронная функция:

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

Здесь другая функция, использующая для и ожидающаяотделка петли

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");
}
0 голосов
/ 18 октября 2019

Вместо использования async/await я предлагаю делать все за один запрос, используя WHERE IN, а не по одному запросу на игрока. Посмотрите, соответствует ли следующее вашим потребностям:

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;

    });

  });
0 голосов
/ 18 октября 2019

Если вы await обещание, оно оценивается как результат этого обещания, поэтому rows это не обещание, это результат . Итак, это:

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

Не имеет особого смысла, просто сделайте:

 return message;

Кроме того, у вас есть await внутри обычной функции, что является синтаксической ошибкой.

Кроме того return list; мало что делает (если это экспресс), возможно, вы захотите return res.json({ list });.

: я выполнил некоторую отладку и, по-видимому, оценил значение i дляцикл увеличивается до разрешения обещания.

Я сомневаюсь, что вы можете отлаживать код, если не можете его запустить из-за синтаксических ошибок.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...