使用JavaScript循环获取并展示指定数量Random User API数据遇阻
解决循环调用Random User API展示多用户的问题
嘿,我来帮你搞定这个问题!先看看你原来代码里的几个关键问题,再给你两种符合需求的实现方案:
为什么你原来的循环没效果?
testapi是Promise不是数组:你定义的testapi是fetch返回的Promise对象,不是数组,所以testapi.length是undefined,注释里的循环条件根本不成立,自然不会执行。- DOM结构和内容覆盖问题:你页面里只有一个
<li>和固定的test/myImg元素,就算循环跑起来,每次设置innerHTML都会把之前的内容覆盖掉,最后只能看到最后一个用户的信息,甚至因为异步顺序问题可能啥都看不到。 - innerHTML拼接的小问题:你在拼接HTML的时候还链式调用了
setAttribute,这个方法返回undefined,会被拼到HTML里,虽然不报错,但属于冗余代码。
方案1:用for循环 + async/await(顺序请求用户)
这种方式会按顺序逐个请求用户,适合你想理解异步循环的逻辑:
首先修改HTML,给ul加个id方便动态添加用户卡片:
<!DOCTYPE html> <html lang="eng"> <head> <meta charset="utf-8"> <link rel="stylesheet" type="text/css" href="style.css"> </head> <body> <div> <ul id="userList"></ul> <!-- 新增id,用来动态插入用户li --> </div> <script src="script.js"></script> </body> </html>
调整CSS让布局更美观:
#userList { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 20px; padding: 20px; list-style: none; } li { display:flex; flex-direction: column; align-items:center; box-shadow: 2px 4px 25px rgba(0, 0, 0, .1); padding: 15px; border-radius: 8px; } img { border-radius: 50%; margin-bottom: 10px; }
JavaScript实现:
// 获取存放用户列表的ul元素 const userList = document.getElementById('userList'); // 封装获取单个男性用户的异步函数 async function getSingleMaleUser() { try { const response = await fetch("https://randomuser.me/api/?gender=male"); const data = await response.json(); return data.results[0]; // 返回单个用户数据 } catch (err) { console.log('请求出错了:', err); return null; } } // 循环加载15个用户并渲染 async function loadUsers() { for (let i = 0; i < 15; i++) { const user = await getSingleMaleUser(); if (user) { renderUser(user); // 渲染单个用户到页面 } } } // 渲染单个用户的函数 function renderUser(user) { // 创建新的li元素 const userItem = document.createElement('li'); // 填充用户信息(用模板字符串更清晰) userItem.innerHTML = ` <h3>${user.gender}</h3> <p>${user.name.first} ${user.name.last}</p> <img src="${user.picture.medium}" alt="${user.name.first}的头像" /> `; // 把li添加到ul里 userList.appendChild(userItem); } // 启动加载 loadUsers();
方案2:用Promise.all + map(并行请求用户)
这种方式会同时发送15个请求,加载速度更快,用map生成请求Promise数组,再用Promise.all等待所有请求完成:
JavaScript代码(HTML和CSS和方案1一样):
const userList = document.getElementById('userList'); // 单个用户请求函数 function getSingleMaleUser() { return fetch("https://randomuser.me/api/?gender=male") .then(res => res.json()) .then(data => data.results[0]) .catch(err => { console.log('请求出错:', err); return null; }); } async function loadUsers() { // 生成15个请求的Promise数组 const userPromises = Array.from({ length: 15 }, () => getSingleMaleUser()); // 等待所有请求完成,拿到所有用户数据 const users = await Promise.all(userPromises); // 过滤掉请求失败的用户,然后逐个渲染 users.filter(user => user !== null).forEach(user => renderUser(user)); } // 和方案1一样的渲染函数 function renderUser(user) { const userItem = document.createElement('li'); userItem.innerHTML = ` <h3>${user.gender}</h3> <p>${user.name.first} ${user.name.last}</p> <img src="${user.picture.medium}" alt="${user.name.first}的头像" /> `; userList.appendChild(userItem); } loadUsers();
小提醒
虽然用循环调用API能帮你加深异步逻辑的理解,但实际项目里更推荐直接用API的results参数一次请求15个用户:https://randomuser.me/api/?gender=male&results=15,这样减少请求次数,性能更好哦~
内容的提问来源于stack exchange,提问作者Xertiem
相关产品推荐
相关产品推荐

