Node.js中如何将查询结果存入对象变量?查询products表返回{}
在Node.js中正确将数据库查询结果存入对象变量的方法
我猜你大概率是踩了Node.js异步操作的坑——数据库查询是异步任务,如果你在查询还没完成的时候就去访问变量,自然会拿到空对象。下面我给你拆解问题,再给出几种靠谱的解决方案:
先看你可能写错的代码(反面例子)
很多新手会犯这个错:在异步回调外面赋值变量,然后立即打印,这时候查询还没执行完,变量根本没被赋值:
const mysql = require('mysql2'); const connection = mysql.createConnection({ host: 'localhost', user: 'your_user', password: 'your_pwd', database: 'your_db' }); let productsObj = {}; // 异步查询:这个回调函数会在查询完成后才执行 connection.query('SELECT * FROM products', (err, results) => { if (err) throw err; productsObj = results; // 这里赋值的时机晚于下面的console.log }); console.log(productsObj); // 先执行,所以输出{}
解决方案1:用async/await(最推荐,代码更易读)
现在主流的做法是用async/await处理异步操作,把异步代码写得像同步代码一样:
// 注意要导入mysql2的promise版本 const mysql = require('mysql2/promise'); async function fetchProducts() { // 建立数据库连接 const connection = await mysql.createConnection({ host: 'localhost', user: 'your_user', password: 'your_pwd', database: 'your_db' }); let productsObj = {}; try { // 等待查询完成,拿到结果 const [results] = await connection.query('SELECT * FROM products'); // 如果需要把数组转成以id为键的对象(方便后续按id查找),用reduce处理 productsObj = results.reduce((acc, product) => { acc[product.id] = product; return acc; }, {}); console.log(productsObj); // 这里能拿到正确的结果 // 所有需要用到productsObj的业务逻辑都放在这里或者之后 processProducts(productsObj); } catch (err) { console.error('查询出错了:', err); } finally { // 别忘了关闭连接 await connection.end(); } } // 调用函数 fetchProducts(); function processProducts(products) { // 这里写你后续的处理逻辑 }
解决方案2:用回调函数(传统写法)
如果不想用async/await,那就确保所有依赖查询结果的代码都放在回调函数内部:
const mysql = require('mysql2'); const connection = mysql.createConnection({ host: 'localhost', user: 'your_user', password: 'your_pwd', database: 'your_db' }); let productsObj = {}; connection.query('SELECT * FROM products', (err, results) => { if (err) { console.error('查询失败:', err); return; } // 转换为你需要的对象格式 productsObj = results.reduce((acc, product) => { acc[product.id] = product; return acc; }, {}); console.log(productsObj); // 这里能正常输出结果 // 所有用到productsObj的操作都要放在这个回调里 doSomethingWithProducts(productsObj); }); function doSomethingWithProducts(products) { // 你的业务代码 }
额外说明
- 如果不需要把数组转成键值对对象,只是想把查询结果存入对象的某个属性,直接赋值就行:
productsObj.data = results; - 不管用哪种方法,核心原则是:所有依赖查询结果的代码必须等待异步查询完成后再执行
内容的提问来源于stack exchange,提问作者m.o
相关产品推荐
相关产品推荐

