Node.js - 如何使用MySQL查询从for循环返回数组回调?

问题描述 投票:1回答:1

我正在尝试获取我的Node.js应用程序上的虚拟社区列表,然后使用回调函数返回它。当我使用回调调用getList()方法时,它返回一个空数组。

const mysqli = require("../mysqli/connect");

class Communities{

  getList(callback){
    var list = [];

    mysqli.query("SELECT * FROM communities", (err, communities) => {

      for(let i = 0; i < communities.length; i++){
        mysqli.query("SELECT name FROM users WHERE id='"+ communities[i].host +"'", (err, host) => {

          list.push({
            "id": communities[i].id,
            "name": communities[i].name,
            "hostID": communities[i].host,
            "hostName": host[0].name,
            "verified": communities[i].verified,
            "people": communities[i].people
          });

        });
      }

      callback(list);
    });
  }

}

new Communities().getList((list) => {
  console.log(list);
});

我需要使循环到异步并在for循环结束时调用回调。请让我知道如何做到这一点。谢谢。

javascript node.js for-loop asynchronous callback
1个回答
2
投票

如果你必须将它们中的多个组合在一起,回调会变得非常难看,这就是为什么Promises被发明来简化它。要在你的情况下使用Promise,你必须在查询数据库时首先创建一个Promise:

 const query = q => new Promise((resolve, reject) => mysqli.query(q, (err, result) => err ? reject(err) : resolve(result)));

现在做多个查询将返回多个promise,可以使用Promise.all组合到一个promise²:

 async getList(){
   const communities = await query("SELECT * FROM communities");

   const result = await/*³*/ Promise.all(communities.map(async community => {
      const host = await query(`SELECT name FROM users WHERE id='${community.host}'`);/*⁴*/

       return {
        ...community,
        hostName: host[0].name,
       };
    }));

    return result;
  }

现在您可以轻松获得结果:

 new Communities().getList().then(list => {
   console.log(list);
 });

继续阅读:

Working with Promises - Google Developers

Understanding async / await - Ponyfoo

笔记:

¹:如果你经常这样做,你可能应该使用一个本机支持promises的mysql库,这可以保证很多工作。

²:通过这些请求是并行完成的,这意味着它比一个接一个地做得更快(可以使用for循环并在其中等待)。

³:那个await是多余的,但我更愿意将它标记为异步动作。

⁴:我想这也可以使用一个SQL查询来完成,所以如果它对你的用例来说太慢了(我怀疑)你应该优化查询本身。

© www.soinside.com 2019 - 2024. All rights reserved.