【问题标题】:Node.js - How to return callback with array from for loop with MySQL query?Node.js - 如何使用 MySQL 查询从 for 循环返回带有数组的回调?
【发布时间】:2019-09-11 15:34:17
【问题描述】:

我正在尝试在我的 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 循环设为异步并在 for 循环结束时调用回调。请让我知道如何做到这一点。谢谢。

【问题讨论】:

  • 你用的是哪个mysqli库?
  • 这可能与 for 循环是同步的事实有关。因此,回调发生在循环本身之前。当您使用回调时,您可以使用一些异步流程来使用它。 Async 是一个很好的库来处理这个
  • 是的,这是它的主要问题,因为回调发生在你写的循环之前,但我不知道如何很好地使用那个库。

标签: javascript node.js for-loop asynchronous callback


【解决方案1】:

如果您必须将多个回调组合起来,回调会变得非常丑陋,这就是发明 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

注意事项:

¹:如果你更频繁地这样做,你可能更愿意使用一个本身支持 Promise 的 mysql 库,这样可以保证很多工作。

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

³:await 是多余的,但我更喜欢保留它以将其标记为异步操作。

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

【讨论】:

  • 谢谢,我试试看。
  • 当我运行脚本时,控制台返回错误:SyntaxError: await is only valid in async function,我已经通过 npm 安装了一个异步库。
  • 你不需要任何库。你的 NodeJS 版本是最新的吗?您是否使用了提供的确切代码? awaits 中的哪一个?
  • 现在我有 8.11.1 版本的 Node.js 和 5.6.0 的 npm。
  • 是的,我使用了您发送的代码,它就是这个 await:var community = await query("SELECT * FROM community");
猜你喜欢
  • 2011-02-21
  • 1970-01-01
  • 2015-08-21
  • 2018-04-06
  • 2021-05-21
  • 2017-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多