Socket.IO异步获取用户数据时循环返回数据异常问题咨询
Hey, let's break down why your getUserData function isn't returning the correct data—it's a classic issue with asynchronous code!
The Root Problem
Socket.IO's emit callback runs asynchronously. Right now, your function executes return { username: username, uid: uid } immediately after calling socket.emit, way before the server sends back the user data and triggers that inner callback. At that point, username and uid aren't even assigned values yet (or might hold old, irrelevant values), so your returned object is empty or incorrect.
Fixes to Try
1. Use a Callback Parameter
Modify getUserData to accept a callback function that will receive the user data once it's available:
function getUserData(uid, onDataReceived) { "use strict"; socket.emit('getUserData', uid, function(callbackData) { console.log('Received callback data:', callbackData); // Note: If callbackData is an array of users (your loop suggests this), // pick the relevant user (here we take the first one; adjust as needed) const user = callbackData[0]; const userData = { username: user.username, uid: user.uid, about: user.about }; // Pass the data to the callback onDataReceived(userData); }); } // How to use it: getUserData('your-user-uid', function(userData) { console.log('Got user data:', userData); // Do whatever you need with userData here (render UI, etc.) });
2. Wrap in a Promise (Modern Approach)
Promises let you handle async code more cleanly, and work with async/await:
function getUserData(uid) { "use strict"; return new Promise((resolve, reject) => { socket.emit('getUserData', uid, function(callbackData) { console.log('Received callback data:', callbackData); if (!callbackData || callbackData.length === 0) { return reject(new Error('No user data found')); } const user = callbackData[0]; const userData = { username: user.username, uid: user.uid, about: user.about }; resolve(userData); }); // Optional: Add a timeout to avoid hanging indefinitely setTimeout(() => { reject(new Error('Request timed out')); }, 5000); }); } // Usage with .then()/.catch(): getUserData('your-user-uid') .then(userData => { console.log('Got user data:', userData); // Handle data here }) .catch(error => { console.error('Failed to get user data:', error); }); // Usage with async/await (inside an async function): async function fetchAndUseUser() { try { const userData = await getUserData('your-user-uid'); console.log('Got user data:', userData); // Handle data here } catch (error) { console.error('Error:', error); } } fetchAndUseUser();
Quick Side Note
Your original loop over callback.length will overwrite username, uid, and about on each iteration—so you'll only end up with the last user's data in the array. If you're expecting a single user, skip the loop entirely and just access callback[0] (or adjust if your server returns a single object instead of an array).
内容的提问来源于stack exchange,提问作者Nik Hendricks

