JavaScript中从两个关联JSON接口获取数据并统计用户发帖量
解决用户与帖子数据关联及统计问题
嘿,我来帮你搞定这个用户和帖子数据关联的需求!你已经用XMLHttpRequest发起了帖子请求,接下来我们只需要把用户数据也拉取到,然后完成关联和发帖数统计即可。下面给你两种实现思路,按需选择:
方式一:用Promise简化异步处理(推荐)
这种写法更清晰,避免嵌套回调,维护起来更方便:
首先封装一个通用的请求函数,减少重复代码:
function fetchData(url) { return new Promise((resolve, reject) => { const xhr = new XMLHttpRequest(); xhr.open('GET', url); xhr.onload = () => { if (xhr.status >= 200 && xhr.status < 300) { resolve(JSON.parse(xhr.responseText)); } else { reject(new Error(`请求失败,状态码:${xhr.status}`)); } }; xhr.onerror = () => reject(new Error('网络请求出错')); xhr.send(); }); }
然后同时发起用户和帖子请求,待两者都返回后处理数据:
// 并行请求用户和帖子数据 Promise.all([ fetchData('https://jsonplaceholder.typicode.com/users'), fetchData('https://jsonplaceholder.typicode.com/posts') ]) .then(([users, posts]) => { // 1. 创建用户ID到用户对象的映射表,实现O(1)快速查找 const userMap = users.reduce((map, user) => { // 给每个用户添加posts数组和postCount统计字段 map[user.id] = { ...user, posts: [], postCount: 0 }; return map; }, {}); // 2. 遍历所有帖子,关联到对应用户并统计数量 posts.forEach(post => { const targetUser = userMap[post.userId]; if (targetUser) { // 确保用户存在(避免数据异常) targetUser.posts.push(post); targetUser.postCount++; } }); // 3. 把映射表转换为数组形式(方便后续遍历使用) const usersWithPosts = Object.values(userMap); // 输出结果示例 console.log('用户关联帖子及统计数据:', usersWithPosts); usersWithPosts.forEach(user => { console.log(`用户「${user.name}」共发布 ${user.postCount} 篇帖子`); }); }) .catch(error => { console.error('数据获取失败:', error); });
方式二:基于你现有代码的嵌套回调写法
如果想延续你原来的XMLHttpRequest嵌套风格,可以这么写:
// 先请求用户数据 const userRequest = new XMLHttpRequest(); userRequest.open('GET', 'https://jsonplaceholder.typicode.com/users'); userRequest.onload = function() { if (userRequest.status >= 200 && userRequest.status < 300) { const users = JSON.parse(userRequest.responseText); // 再请求帖子数据 const postRequest = new XMLHttpRequest(); postRequest.open('GET', 'https://jsonplaceholder.typicode.com/posts'); postRequest.onload = function() { if (postRequest.status >= 200 && postRequest.status < 300) { const posts = JSON.parse(postRequest.responseText); // 构建用户映射表 const userMap = {}; users.forEach(user => { userMap[user.id] = { ...user, posts: [], postCount: 0 }; }); // 关联帖子并统计 posts.forEach(post => { const user = userMap[post.userId]; if (user) { user.posts.push(post); user.postCount++; } }); // 处理后的结果 const usersWithPosts = Object.values(userMap); console.log(usersWithPosts); } else { console.error('帖子请求失败,状态码:', postRequest.status); } }; postRequest.onerror = function() { console.error('帖子请求网络出错'); }; postRequest.send(); } else { console.error('用户请求失败,状态码:', userRequest.status); } }; userRequest.onerror = function() { console.error('用户请求网络出错'); }; userRequest.send();
核心思路说明
- 异步数据获取:确保用户和帖子数据都请求完成后再处理,避免因异步顺序导致的数据缺失
- 映射表优化:用用户ID作为键创建映射表,避免遍历用户数组查找对应帖子作者,提升处理效率
- 数据关联与统计:遍历帖子时直接通过映射表找到对应用户,添加帖子并累加计数
内容的提问来源于stack exchange,提问作者reshape
相关产品推荐
相关产品推荐

