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

Node.js类中方法返回undefined及this._data丢失问题求助

问题分析与解决方案

咱们来一步步拆解你遇到的两个核心问题:

1. getQuests 方法返回 undefined 的原因

connection.query 是异步操作——它不会阻塞代码执行,当你调用 getQuests() 时,函数会立刻执行到 connection.query() 这一行,然后直接结束(没有返回任何值,所以默认返回 undefined)。而你写在回调函数里的 return structure,只是回调自身的返回值,根本不会被外部的调用者获取到。

简单说:你的 return 语句在异步回调里,等它执行的时候,getQuests 早就已经执行完了。

2. this._data 数据丢失的问题

在JavaScript的普通函数回调中(比如你传给 connection.query 的匿名函数),this 的上下文会发生变化——它不再指向你的类实例,而是指向调用这个回调的对象(这里是和connection相关的上下文)。虽然你的代码里在回调外部提前取了 id 和 lvl,暂时没影响,但如果后续在回调里需要访问 this._data,就会拿到错误的值;另外如果异步过程中类实例被意外修改,也可能导致数据丢失,但核心问题还是回调的this指向偏差。


修复方案

我们可以用Promise + async/await来处理异步逻辑,同时用箭头函数或提前保存上下文来解决this指向问题:

重构后的代码示例

method.getQuests = async function() {
  // 提前保存当前类实例的上下文,避免回调中this指向混乱
  const self = this;
  const id = self._data[0].id;
  const lvl = self._data[0].level;
  const structure = [];

  // 将异步的query操作包装成Promise,方便用await等待结果
  const rows = await new Promise((resolve, reject) => {
    connection.query("SELECT * FROM quest WHERE player_id = ?", [id], function(errors, rowss) {
      if (errors) {
        reject(errors);
        return;
      }
      resolve(rowss);
    });
  });

  // 处理查询到的结果
  for(let i = 0; i < rows.length; i++){
    const rewards = { 
      "coins": rows[i].gold, 
      "xp": rows[i].experience, 
      "honor": rows[i].honor, 
      "premium": rows[i].donut, 
      "statPoints": 0, 
      "item": 0 
    };
    structure.push({
      "id": rows[i].id,
      "character_id": id,
      "identifier": rows[i].name,
      "type": 1,
      "stage": rows[i].stage,
      "level": lvl,
      "status": 1,
      "duration_type": 1,
      "duration_raw": (rows[i].duration * 60) * 4,
      "duration": rows[i].duration * 60,
      "ts_complete": 0,
      "energy_cost": rows[i].duration,
      "fight_difficulty": 0,
      "fight_npc_identifier": "",
      "fight_battle_id": 0,
      "used_resources": 0,
      "rewards": JSON.stringify(rewards)
    });
  }

  return structure;
};

关键修改点:

  • 用async标记方法,将异步查询包装成Promise并通过await等待完成,这样return structure就能正确返回结果
  • 提前保存self = this确保上下文正确,你也可以把query的回调换成箭头函数(箭头函数会自动继承外部的this)
  • 增加了错误处理逻辑,将查询错误通过reject抛出,方便调用方捕获并处理

调用方式

因为方法现在是async函数,调用时需要用await或者.then():

// 在async函数内部调用
const quests = await yourClassInstance.getQuests();

// 或者用.then()链式调用
yourClassInstance.getQuests().then(quests => {
  console.log(quests);
}).catch(err => {
  console.error('查询任务列表出错:', err);
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:35:15