NodeJS+Express下多Axios嵌套请求获取用户信息问题求助
Hey there! Let's walk through what's going wrong with your code and fix it so you get that exact user array format you need. I'll break down the issues first, then show you the corrected code with explanations.
Key Issues in Your Current Code
Unresolved Async Operations in
getAllUsers()
Yourmapcall in the.then()block runsgetUser()(an async function) but doesn't wait for those promises to resolve. Plus, you aren't returning the mapped results, sousersends up asundefined.Missing Object Initialization & Return in
getUser()
You try to assign properties touserwithout initializing it first (so you'll get a reference error), and the.then()block doesn't return the assembled user object—meaninggetUser()always returnsundefined.Unnecessary Mix of
awaitand.then()
Using both in async functions makes the code harder to read and debug. Sticking withawaitgives you a linear, easier-to-follow flow.Silent Error Handling
Yourcatchblocks only log errors but don't handle them (like returning a fallback value or propagating the error), so you might not even know when a fetch fails.
Corrected Code
First, let's fix the getUser() function:
async function getUser(name) { try { // Initialize the user object first to avoid reference errors const user = {}; // Use await with axios.all() for cleaner, linear async code const [friendRes, playsRes] = await axios.all([ axios.get(`http://localhost:8000/friends/${name}`), axios.get(`http://localhost:8001/plays/${name}`) ]); // Populate the user object with your required fields user.username = name; user.friends = friendRes.data.friends.length; user.plays = playsRes.data.plays.length; user.uri = `/users/${name}`; // Return the fully assembled user object return user; } catch (error) { console.error(`Failed to fetch data for user ${name}:`, error); // Optional: Return a fallback user instead of breaking the whole flow return { username: name, friends: 0, plays: 0, uri: `/users/${name}` }; // Or uncomment below to propagate the error if you want to handle it upstream // throw error; } }
Now fix getAllUsers() to properly handle the array of async calls:
async function getAllUsers() { try { // Fetch the initial friends list using await const friendsResponse = await axios.get('http://localhost:8000/friends'); const friendUsernames = friendsResponse.data.friends; // Map each username to a getUser promise, then wait for all to resolve const users = await Promise.all( friendUsernames.map(username => getUser(username)) ); // Optional: Filter out any fallback/failed users if needed return users.filter(user => user.username !== undefined); } catch (error) { console.error('Failed to fetch the initial friends list:', error); // Return an empty array as a fallback for critical errors return []; } }
What Changed & Why
getUser()Improvements:- Added
try/catchfor structured error handling instead of.catch()chains - Initialized the
userobject before assigning properties to avoid reference errors - Used array destructuring with
await axios.all()to make the code more readable - Explicitly returns the assembled user object so
getAllUsers()gets valid data - Added a fallback user option to prevent a single failed fetch from breaking the entire user list
- Added
getAllUsers()Improvements:- Removed the mix of
awaitand.then()for a linear, easy-to-follow flow - Used
Promise.all()to wait for allgetUsercalls to complete (sincemapreturns an array of promises) - Added filtering to clean up any fallback users (if you used that option)
- Centralized error handling for the initial friends list fetch
- Removed the mix of
Extra Tips for Robustness
- Add Type Checks: Before accessing
.lengthonfriendRes.data.friendsorplaysRes.data.plays, check if those properties exist (e.g.,friendRes.data?.friends?.length || 0) to avoid unexpected errors if the API returns malformed data. - Rate Limiting/Batching: If you have a large number of friends, add rate limiting or batch requests to avoid hitting API rate limits.
- Caching: Cache user data if it doesn't change frequently to reduce redundant API calls and speed up responses.
内容的提问来源于stack exchange,提问作者Rafael López Dorado

