【问题标题】:Async functions in for loops javascriptfor循环javascript中的异步函数
【发布时间】:2019-10-19 03:46:44
【问题描述】:

我对异步函数没有经验,我想在 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;
  });
});

实际上这是完整的问题:我做了一些调试,显然在解决承诺之前,for 循环中的 i 值增加了。另外,正如我提到的,我不熟悉异步函数,您能否提供一个关于 Promise 和异步函数如何工作的描述性资源?

谢谢

注意:为了更好的缩进,代码如下:https://hastebin.com/fovayucodi.js

【问题讨论】:

  • 不要忘记返回你希望外部从你的异步函数接收的内容。
  • 请在您的帖子中提供更好的缩进,而不是某些外部网站

标签: javascript node.js asynchronous


【解决方案1】:

我建议不要使用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;

    });

  });

【讨论】:

    【解决方案2】:

    如果你await 一个承诺,它会评估为该承诺的result,所以rows 不是一个承诺,它是 result。所以这个:

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

    没有多大意义,做吧:

     return message;
    

    另外,您在常规函数中有一个await,这是一个语法错误。

    另外,return list; 没有太多作用(如果是快递的话),您可能想要return res.json({ list });

    :我做了一些调试,显然在解决承诺之前,for 循环中的 i 值增加了。

    如果由于语法错误而无法实际运行代码,我怀疑是否可以调试代码。

    【讨论】:

      【解决方案3】:

      尝试使用 for-of 而不是只使用 for。

      类似这样的:

      异步函数:

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

      这里另一个函数使用 for 并等待循环结束

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

      【讨论】:

      • 如果您可以扩展您的答案以包括一些关于您的答案中发生的事情的解释,以明确如何在循环中使用异步,这将使 OP 和同一级别的读者受益。可以链接到异步 MDN 页面等更多详细信息。
      猜你喜欢
      • 2014-07-09
      • 2017-12-16
      • 2012-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-07
      • 2018-09-24
      • 1970-01-01
      相关资源
      最近更新 更多