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

如何将MySQL查询结果保存到JavaScript对象属性?解决异步问题

问题解决:异步查询导致Game对象属性未正确赋值

核心问题分析

你的代码存在两个关键问题:

  • SQL查询逻辑错误:WHERE id=id会被解析为查询所有id字段等于自身的记录,而非传入的参数id,根本查不到目标数据。
  • 异步操作时序问题:db.query是异步回调方法,调用firstGame.fetchGame(1)后会立即执行console.log,此时数据库查询还未完成,对象属性自然还是初始的null。

修复方案(基于Promise + async/await)

修改Game.js

const db = require('../mySqlConnection');

class Game{
   constructor(){
        this.id = null;
        this.player1 = null;
        this.player2 = null;
   }

    saveData(data) {
        // 数据库查询结果是数组,取第一条有效数据
        const gameData = data[0];
        this.id = gameData.id;
        this.player1 = gameData.player1;
        this.player2 = gameData.player2;
    }

    // 将fetchGame改为返回Promise的方法,便于异步控制
    fetchGame(id){
        return new Promise((resolve, reject) => {
            // 用占位符?传递参数,修正查询逻辑同时避免SQL注入
            const q = "SELECT * FROM `games` WHERE `id` = ?";
            
            db.query(q, [id], (err, data) => {
                if(err) {
                    reject(err);
                    return;
                }
                this.saveData(data);
                resolve(this); // 查询完成后返回当前实例
            })
        })
    }
}

module.exports = Game

修改index.js

const Game = require('./components/game')

// 用async函数包裹异步逻辑,等待查询完成后再打印结果
async function initGame() {
    var firstGame = new Game()
    await firstGame.fetchGame(1);
    console.log("index.js: " + JSON.stringify(firstGame))
}

initGame();

更优实现方式

可以用静态工厂方法直接创建并初始化Game实例,省去先创建空对象再赋值的冗余步骤,代码更简洁健壮:

// Game.js优化版
const db = require('../mySqlConnection');

class Game{
   constructor(gameData){
        this.id = gameData.id;
        this.player1 = gameData.player1;
        this.player2 = gameData.player2;
   }

    // 静态工厂方法,直接返回初始化完成的Game实例
    static async fetchGame(id){
        return new Promise((resolve, reject) => {
            const q = "SELECT * FROM `games` WHERE `id` = ?";
            
            db.query(q, [id], (err, data) => {
                if(err) {
                    reject(err);
                    return;
                }
                if(data.length === 0) {
                    reject(new Error("未找到对应游戏记录"));
                    return;
                }
                const game = new Game(data[0]);
                resolve(game);
            })
        })
    }
}

module.exports = Game

对应的index.js

const Game = require('./components/game')

async function initGame() {
    try {
        const firstGame = await Game.fetchGame(1);
        console.log("index.js: " + JSON.stringify(firstGame))
    } catch (err) {
        console.error(err);
    }
}

initGame();

额外注意事项

  • 始终使用参数占位符?传递SQL查询参数,避免SQL注入风险。
  • 必须处理数据库查询的异常情况(比如找不到对应记录),避免程序意外崩溃。

内容的提问来源于stack exchange,提问作者Lukas Walter

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 17:27:14