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

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();

核心思路说明

  1. 异步数据获取:确保用户和帖子数据都请求完成后再处理,避免因异步顺序导致的数据缺失
  2. 映射表优化:用用户ID作为键创建映射表,避免遍历用户数组查找对应帖子作者,提升处理效率
  3. 数据关联与统计:遍历帖子时直接通过映射表找到对应用户,添加帖子并累加计数

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:44:23