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

如何在map函数中实现异步增量数据获取 满足剧集分步加载需求

问题根因

你之前的实现确实和async/await在map中的使用问题相关,核心有几个问题:

  • Array.map 传入async函数时,返回的是promise数组,你没有对这些promise做等待处理,外层的try/catch无法捕获内部异步请求抛出的错误
  • 你在每个请求的前后都修改isLoading,会导致第一个请求完成就把加载状态设为false,不符合「所有请求完成后才隐藏加载指示器」的需求
  • 多个异步请求并发执行时,返回顺序不确定,最后渲染的剧集顺序可能和原season.episodes的顺序不一致
原生React实现方案

如果你不需要引入额外库,可以根据业务需求选择对应的实现方式:

串行请求方案(保证剧集按原有顺序渲染,符合常规观看习惯)

const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState('');
const [data, setData] = useState([]);

const handleClick = async () => {
  // 点击后先初始化状态,打开全局加载
  setIsLoading(true);
  setError('');
  setData([]);
  try {
    // 用for of循环保证请求按顺序执行,逐个返回渲染
    for (const episode of season.episodes) {
      const links = await publicQueryClientApi(
        `${process.env.NEXT_PUBLIC_SERVER_URL}/download/${episode.slug}`
      );
      setData((prev) => [...prev, { episode, links }]);
    }
  } catch (error) {
    setData([]);
    setError(error.message);
  } finally {
    // 所有请求完成/出错,统一关闭加载状态
    setIsLoading(false);
  }
};

并发请求方案(请求速度更快,同时保证渲染顺序和原数组一致)

const handleClick = async () => {
  setIsLoading(true);
  setError('');
  setData([]);
  try {
    // 并发发起所有请求
    const requestPromises = season.episodes.map(async (episode) => {
      const links = await publicQueryClientApi(
        `${process.env.NEXT_PUBLIC_SERVER_URL}/download/${episode.slug}`
      );
      return { episode, links };
    });
    // 按原数组顺序逐个处理返回结果,保证渲染顺序正确
    for (const promise of requestPromises) {
      const res = await promise;
      setData(prev => [...prev, res]);
    }
  } catch (error) {
    setData([]);
    setError(error.message);
  } finally {
    setIsLoading(false);
  }
};
RxJS适用性说明

RxJS完全适用于这个场景,它对这种异步流、逐个返回数据的场景处理能力很强,你可以用from把剧集数组转成可观察对象,再用mergeMap或者concatMap控制并发请求,用scan操作符累积返回的剧集数据,不需要手动维护state的更新逻辑,还能很方便的实现请求取消、重试、限流等额外能力,如果后续你的数据流逻辑变复杂,非常推荐引入RxJS来实现。

内容的提问来源于stack exchange,提问作者Yassine Bridi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 08:45:04