在Array.prototype.map()中使用Fetch实现用户邮箱提取的问题
问题:从Mock API获取用户列表后,使用map结合Fetch转换为仅含邮箱的对象失败
我需要从Mock API获取用户列表,然后在Array.prototype.map()中用Fetch将每个用户转换为仅包含邮箱的对象,但代码无法得到预期结果:
// 返回10个用户的Mock API请求函数 function getUsers() { return fetch('https://jsonplaceholder.typicode.com/users') .then(res => res.json()) .then(data => { console.log(data) return data }) } // 试图获取可遍历的用户列表 const usersList = getUsers() // 通过用户ID请求单个用户数据,提取邮箱 const mappedUsers = (users) => { return users.map(async user => { const response = await fetch(`https://jsonplaceholder.typicode.com/users/${user.id}`) const userData = await response.json() return { userEmail: userData.email } }) } mappedUsers(usersList)
预期输出:
[ { userEmail: 'name of the first email from api' }, { userEmail: '...' }, ... ]
问题原因与解决方案
核心问题
usersList是Promise而非实际数组:getUsers()返回的是Promise对象,直接传给mappedUsers时,map会在Promise上执行,而非遍历真实的用户数组。map返回Promise数组:map中使用async函数时,每个迭代项都会变成Promise,所以mappedUsers返回的是一组未完成的Promise,不是预期的对象数组。
修正代码(保留二次请求逻辑)
先等待getUsers()的Promise resolve得到实际数组,再用Promise.all等待所有二次请求完成:
function getUsers() { return fetch('https://jsonplaceholder.typicode.com/users') .then(res => res.json()) } const mappedUsers = async (users) => { // 用Promise.all等待所有fetch请求完成,转换为最终的对象数组 return Promise.all(users.map(async user => { const response = await fetch(`https://jsonplaceholder.typicode.com/users/${user.id}`) const userData = await response.json() return { userEmail: userData.email } })) } // 用自执行异步函数处理完整Promise流程 (async () => { const usersList = await getUsers() const result = await mappedUsers(usersList) console.log(result) // 符合预期的对象数组 })()
优化方案(无需二次请求)
实际上第一次getUsers()已经返回了所有用户的完整数据,包括邮箱,完全不需要再次调用单个用户的API,直接提取即可:
function getUsers() { return fetch('https://jsonplaceholder.typicode.com/users') .then(res => res.json()) } const mappedUsers = (users) => { // 直接从已获取的用户数据中提取邮箱 return users.map(user => ({ userEmail: user.email })) } (async () => { const usersList = await getUsers() const result = mappedUsers(usersList) console.log(result) })()
内容的提问来源于stack exchange,提问作者dbzx10299
相关产品推荐
相关产品推荐

