WebSocket获取用户后return返回undefined,但console.log可正常打印用户
解决WebSocket异步获取数据返回undefined的问题
问题根源
- 函数无顶层返回值:
fetchUser函数本身没有任何顶层return语句,它仅注册了WebSocket的事件回调,函数执行完毕后直接返回undefined——回调函数里的return只会终止回调本身,和外部函数的返回值无关。 - 异步执行特性: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
相关产品推荐
相关产品推荐

