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

async/await结合Fetch调用API 如何等待全部请求完成后统一渲染

问题根因

你当前的async/await写法在for循环内逐个await接口请求,且每拿到单个接口的返回结果就立刻操作DOM渲染内容,因此每完成一个接口调用就会触发一次页面渲染,自然无法等到5个接口全部返回后统一展示。
顺带说明:你之前的.then链式调用版本本身也没有实现「全量请求完成再渲染」的逻辑,只是当时接口响应速度快,你没有感知到逐次渲染的问题。

修复方案

核心逻辑非常直接:请求阶段只做数据拉取,把所有返回结果存在本地变量里,等5个接口全部完成后,再一次性拼接HTML插入DOM,最后隐藏加载动画,绝对不要在请求循环的过程中做任何DOM操作。

基础修复版代码(串行请求)

async function getPhotosFromAPI() {
  // 存储所有相册数据,请求阶段不操作DOM
  const allAlbums = [];
  for (let i = 1; i <= 5; i++) {
    const response = await fetch(`https://jsonplaceholder.typicode.com/photos/?albumId=${i}`);
    const photoList = await response.json();
    allAlbums.push({
      albumId: i,
      // 每个相册只取前5张图
      photos: photoList.slice(0, 5)
    })
  }
  return allAlbums;
}

async function showPhotos() {
  // 初始化显示加载动画
  document.getElementById("loader").style.display = "block";
  // 等待所有接口数据全部拉取完成
  const allAlbumData = await getPhotosFromAPI();
  // 一次性拼接完整HTML字符串
  let fullHtml = '';
  allAlbumData.forEach(album => {
    fullHtml += `<div class="album${album.albumId}">`;
    album.photos.forEach(photo => {
      fullHtml += `<img src="${photo.url}" alt="album${album.albumId} photo"/>`
    })
    fullHtml += `</div>`;
  })
  // 一次性插入DOM,仅触发一次页面渲染
  document.querySelector(".display-images").innerHTML = fullHtml;
  // 所有渲染完成后隐藏加载动画
  document.getElementById("loader").style.display = "none";
}

showPhotos();

性能优化版(并行请求)

如果不需要强制按顺序发起请求,可以用Promise.all并行拉取5个接口,整体加载速度会比串行逐个await快很多:

async function getPhotosFromAPI() {
  // 批量生成5个接口请求的Promise
  const requestTasks = Array.from({length: 5}, (_, idx) => {
    const albumId = idx + 1;
    return fetch(`https://jsonplaceholder.typicode.com/photos/?albumId=${albumId}`)
      .then(res => res.json())
      .then(photoList => ({
        albumId,
        photos: photoList.slice(0,5)
      }))
  })
  // 并行等待所有请求完成
  return Promise.all(requestTasks);
}
// showPhotos 逻辑和上面基础版完全一致即可
原有代码问题汇总
  • 在for循环请求阶段每拿到单个接口返回就操作DOM插入内容,是导致逐次渲染的直接原因
  • document.getElementById("#loader")写法错误:getElementById参数直接传id字符串即可,不需要加CSS选择器的#前缀
  • 原有.then版本拼接HTML时div标签闭合错误,末尾写的是<div>而非</div>,会导致DOM结构异常
  • 多次零散修改innerHTML会触发浏览器多次重绘重排,性能差;一次性拼接完整HTML再插入DOM,只会触发一次渲染,页面流畅度更高

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 10:18:18