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

JavaScript API数据未加载完成提前渲染HTML的问题解决咨询

解决方案

核心问题原因

  • forEach遍历调用异步函数unqReleaseCoversUrl时不会等待异步请求完成,会直接执行后续的数组过滤、函数返回逻辑,导致await loadTrackDetail结束时封面请求还未完成,coverUrlArray为空
  • 每次查询新曲目时未清空coverUrlArray,导致旧数据不断累加

代码修改步骤

1. 修改unqReleaseCoversUrl函数

调整该函数为返回当前发行版的有效封面数组,避免直接修改全局变量产生副作用,同时增加异常兼容,单个封面请求失败不中断整体流程:

export const unqReleaseCoversUrl = async function (mbid) {
  try {
    const coverData = await GET_JSON(
      encodeURI(`${CONSTANTS.COVER_API_URL}${mbid}`)
    );
    // 直接返回当前发行版的有效封面数组
    return coverData.images
      .filter(image => image.thumbnails["500"])
      .map(image => image.thumbnails["500"]);
  } catch (err) {
    console.warn(`获取发行版${mbid}封面失败:`, err);
    // 请求失败返回空数组,不中断整体流程
    return [];
  }
};

2. 修改loadTrackDetail函数

新增清空旧封面数据的逻辑,用Promise.all等待所有封面请求完成后再继续执行:

export const loadTrackDetail = async function (id) {
  try {
    // 每次查询前先清空旧封面数据,解决旧数据累加问题
    details.coverUrlArray = [];

    const trackData = await GET_JSON(
      encodeURI(
        `${CONSTANTS.API_URL}${id}?inc=genres+artists+ratings+releases&fmt=json`
      )
    );

    details.trackDetails = {
      trackTitle: trackData.title ?? "No title provided",
      trackID: trackData.id,
      trackReleaseDate: trackData["first-release-date"] ?? "No date provided",
      trackLength: trackData.length
        ? CONVERT_MILLIS_TO_MINS_SECONDS(trackData.length)
        : "No duration provided",
      trackArtists: trackData["artist-credit"].length
        ? trackData["artist-credit"]
        : "No information on artists",
      trackReleasesBase: trackData["releases"].length
        ? trackData["releases"]
        : "No information on releases",
      trackReleasesCleanOne: trackData["releases"].length
        ? trackData["releases"].map((release) => ({
            id: release.id,
            title: release.title,
          }))
        : "No information on releases",

      trackGenres: trackData["genres"].length
        ? trackData["genres"]
        : "No information on genres",
      trackRating: trackData.rating.value ?? "No rating yet",
    };

    if (details.trackDetails.trackReleasesCleanOne.length > 0) {
      // 生成所有封面请求的Promise数组
      const coverPromises = details.trackDetails.trackReleasesCleanOne.map((mbid) =>
        unqReleaseCoversUrl(mbid.id)
      );
      // 等待所有请求完成,扁平化结果后存入全局数组
      const coverResults = await Promise.all(coverPromises);
      details.coverUrlArray = coverResults.flat();
    }

    console.log(details.coverUrlArray);
  } catch (err) {
    throw err;
  }
};

逻辑说明

  • 控制器层代码无需修改,原有的await detailsModel.loadTrackDetail(trackID)会等待所有封面数据准备完成后,再执行后续的渲染逻辑,此时传入renderCovers的数组已经包含全部有效封面地址
  • 如果API有请求频率限制,可将Promise.all替换为分批请求的逻辑,避免触发接口限流

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.17 12:45:07