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

WebSocket获取用户后return返回undefined,但console.log可正常打印用户

解决WebSocket异步获取数据返回undefined的问题

问题根源

  1. 函数无顶层返回值:fetchUser函数本身没有任何顶层return语句,它仅注册了WebSocket的事件回调,函数执行完毕后直接返回undefined——回调函数里的return只会终止回调本身,和外部函数的返回值无关。
  2. 异步执行特性:WebSocket的onmessage回调是异步触发的,当你调用fetchUser(1)时,函数立刻执行完并返回undefined,而服务器返回的用户数据要等后续回调触发时才会拿到,此时外部的console.log(fetchUser(1))早已执行完毕。

解决方案:用Promise封装异步逻辑

将fetchUser改为返回Promise,通过resolve传递成功获取的用户数据,reject传递错误信息,调用时用异步方式获取结果。

修改后的代码:

export function fetchUser(id: number) {
  return new Promise((resolve, reject) => {
    const connection = generateConnection();
    
    connection.onopen = () => {
      // 修复原代码中多余的JSON.stringify嵌套问题
      connection.send(JSON.stringify({
        "msg": "connect",
        "version": "1",
        "support": ["1", "pre2", "pre1"]
      }));
      connection.send(JSON.stringify({
        "msg": "method",
        "id": "1",
        "method": "Users.getUser",
        "params": [id]
      }));
    };

    connection.on('message', (event) => {
      const data = event.toString();
      if (data[0] === 'a') {
        try {
          const parsedData = JSON.parse(data.substring(1));
          const a = JSON.parse(parsedData[0]);
          if (a.msg === 'result') {
            connection.close();
            if ('error' in a) {
              reject(new Error(a.error.error));
            } else {
              resolve(a.result);
            }
          }
        } catch (parseErr) {
          reject(parseErr);
          connection.close();
        }
      }
    });

    // 处理WebSocket连接错误
    connection.onerror = (err) => {
      reject(err);
      connection.close();
    };
  });
}

// 调用方式1:使用async/await(推荐)
async function getUserData() {
  try {
    const user = await fetchUser(1);
    console.log(user); // 正常输出用户数据
  } catch (error) {
    console.error('获取用户失败:', error);
  }
}
getUserData();

// 调用方式2:使用.then()链式调用
fetchUser(1)
  .then(user => console.log(user))
  .catch(error => console.error('获取用户失败:', error));

关键修改说明

  • 用Promise包裹整个WebSocket流程,统一管理异步结果和错误
  • 修复了原代码中重复JSON.stringify的问题(原代码将已转义的字符串再次转义,会导致解析失败)
  • 添加了连接错误、解析错误的捕获逻辑,避免异常未处理
  • 调用时必须使用异步方式获取结果,因为Promise的状态是异步更新的

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 17:45:37