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

Node.js异步编程求助:获取帖子后关联用户详情失败

解决异步添加用户详情到帖子的Promise过早resolve问题

你的判断完全正确——addUserDetails函数里的resolve(posts)确实过早执行了。posts.map内部的fetchUser是异步操作,这些请求还没完成、还没把userDetails挂载到对应post对象上,你就已经把原始posts数组返回了,所以后续打印自然看不到预期的userDetails字段。

修正方案

核心思路是等待所有异步获取用户的操作完成后,再返回更新后的posts数组,这里用Promise.all来实现最直接:

方案1:将addUserDetails改为async函数

const fetch = require('node-fetch');

// Async function to retrieve the user details for a given user Id
const fetchUser = async (userId) => {
  const response = await fetch(`https://jsonplaceholder.typicode.com/users/${userId}`);
  return response.json();
};

const addUserDetails = async (posts) => {
  // 为每个post创建一个异步任务:获取用户并挂载到post对象
  const updateTasks = posts.map(async (post) => {
    const userDetails = await fetchUser(post.userId);
    post.userDetails = userDetails;
    return post;
  });

  // 等待所有异步任务完成
  await Promise.all(updateTasks);
  return posts;
};

// Async function to retrieve all posts
const fetchPosts = async () => {
  const response = await fetch('https://jsonplaceholder.typicode.com/posts');
  return response.json();
};

fetchPosts()
  .then(posts => addUserDetails(posts))
  .then(postsWithUserDetails => {
    console.log(postsWithUserDetails[0]);
  })
  .catch(err => console.log(err));

方案2:用Promise.all替代手动创建Promise

如果你不想用async函数,也可以直接通过Promise.all封装所有异步请求:

const addUserDetails = (posts) => {
  // 生成所有获取用户并更新post的Promise数组
  const promises = posts.map(post => 
    fetchUser(post.userId)
      .then(userDetails => {
        post.userDetails = userDetails;
        return post;
      })
  );
  // 等待所有Promise完成后返回结果
  return Promise.all(promises);
};

为什么原代码会失败?

原代码中,posts.map只是触发了一系列异步请求,但并没有等待这些请求完成。resolve(posts)会在map执行完毕后立刻调用——这时候所有fetchUser请求还处于pending状态,userDetails根本还没被添加到post对象上,所以后续拿到的是未修改的原始posts数组。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 01:40:27