You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Node.js与MySQL将数据存入数组?异步查询返回空数组问题排查

根本原因

  • 该问题是典型的Node.js 异步 IO 执行顺序问题,MySQL 的 connection.query 为异步非阻塞方法,回调函数仅会在 SQL 查询完成后才会执行,不会阻塞主线程代码运行
  • 原代码在循环触发所有子查询请求后立刻执行了 res.send 返回响应,此时所有子查询的回调都还未触发,arrStoreChildData 未被推入任何数据,因此返回空数组

修复方案

方案一:async/await 写法(推荐)

先将 query 方法 promisify 化,用 async/await 控制执行顺序,代码可读性更高:

// 引入util模块的promisify方法将callback形式的query转为返回promise的方法
const util = require('util');
const query = util.promisify(connection.query).bind(connection);

let categoryget = async (req, res) => {
  try {
    let arrStoreParentData = [];
    let arrStoreChildData = [];
    // 等待第一个父查询执行完成
    const rst_parent = await query(` SOME SQL QUERY { FIRST QUERY } ='none'`);
    // 生成所有子查询的promise数组
    const childQueryTasks = rst_parent.map(async (parentItem) => {
      const parent_name = parentItem.category_slug;
      arrStoreParentData.push(parent_name);
      // 执行子查询
      const rst_child = await query(` SOME SQL QUERY { SECOND QUERY }=? `, [parent_name]);
      arrStoreChildData.push(rst_child);
    });
    // 等待所有子查询全部执行完成
    await Promise.all(childQueryTasks);
    // 所有查询完成后再返回结果
    return res.send({ arrStoreChildData });
  } catch (err) {
    console.log(err);
    return res.send({ msg: err });
  }
}

方案二:回调兼容写法

如果不想改动原有回调逻辑,可以手动统计子查询完成数量,全部完成后再返回响应:

let categoryget = (req,res)=>{
    //get live category Data
    let arrStoreParentData = new Array(); //store parent id  
    let arrStoreChildData = new Array(); // arr-store all category 
    connection.query(` SOME SQL QUERY { FIRST QUERY } ='none'`,
    (err_parent,rst_parent)=>{
            if(err_parent){
                console.log(err_parent);
                return res.send({msg:err_parent});
            }else{
                // 统计子查询总数和已完成数量
                const totalChildCount = rst_parent.length;
                let finishedChildCount = 0;
                //loop for getting the data  
                //for parent  
                for(var x=0; x < rst_parent.length ; x++){
                    let parent_name = rst_parent[x].category_slug;
                    arrStoreParentData.push(parent_name); 
                    loopchild(parent_name);
                }  
                function loopchild(zz){ 
                    connection.query(` SOME SQL QUERY { SECOND QUERY }=? `,
                    [zz],(err_child,rst_child)=>{
                        if(err_child){
                            console.log(err_child);
                            return res.send({msg:err_child});
                        }else{ 
                            let child_data = rst_child;  
                            arrStoreChildData.push(child_data);
                            finishedChildCount++;
                            // 所有子查询都执行完成后再返回
                            if(finishedChildCount === totalChildCount) {
                                return res.send({arrStoreChildData});
                            }
                        } 
                    }); 
                } 
            }
    });   
}

内容的提问来源于stack exchange,提问作者manas singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 01:15:00