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

如何在for of循环中为每个迭代单独实现lodash防抖?

问题分析

你遇到的核心问题是:lodash的debounce函数在连续调用时会重置延迟计时器。在for循环中快速调用同一个debouncedFetchData函数10次,防抖机制会取消前9次调用,只保留最后一次执行,最终导致animeData仅存入1个对象。

解决方案

方案一:为每个ID创建独立防抖函数

要实现每个迭代单独防抖,必须为每个请求ID生成独立的防抖函数,避免共用计时器。可以用useRef缓存每个ID对应的防抖实例:

import { useEffect, useState, useMemo, useCallback, useRef } from 'react';
// ... 其他导入

const AnimeRecommendations = ({id}) => {
  // ... 其他状态和hooks

  // 缓存每个id对应的防抖函数
  const debouncedFetches = useRef({});

  // 动态获取或创建对应id的防抖函数
  const getDebouncedFetch = useCallback((id) => {
    if (!debouncedFetches.current[id]) {
      debouncedFetches.current[id] = debounce(async () => {
        const anime = await fetchAnimeData(id);
        setAnimeData(prevData => [...prevData, anime]);
      }, 1000);
    }
    return debouncedFetches.current[id];
  }, []);

  useEffect(() => {
    const fetchDataForRecommendations = () => {
      if (recommendations.length) {
        // 先清空数据,避免旧数据干扰
        setAnimeData([]);
        recommendations.forEach(item => {
          const fetchFn = getDebouncedFetch(item.entry.mal_id);
          fetchFn();
        });
      }
    };

    fetchDataForRecommendations();

    // 组件卸载时清理所有防抖计时器,避免内存泄漏
    return () => {
      Object.values(debouncedFetches.current).forEach(fn => fn.cancel());
    };
  }, [recommendations, getDebouncedFetch]);

  // ... 其他渲染逻辑
}

方案二:改用间隔执行(控制请求频率)

如果你的真实需求是避免一次性发送大量请求,而是每隔1秒发起一个请求,无需每个请求单独防抖,可以用递归+setTimeout实现:

useEffect(() => {
  const fetchDataForRecommendations = async () => {
    setAnimeData([]);
    if (!recommendations.length) return;

    // 递归逐个发起请求,间隔1秒
    const fetchNext = async (index) => {
      if (index >= recommendations.length) return;
      const item = recommendations[index];
      const anime = await fetchAnimeData(item.entry.mal_id);
      setAnimeData(prev => [...prev, anime]);
      setTimeout(() => fetchNext(index + 1), 1000);
    };

    fetchNext(0);
  };

  fetchDataForRecommendations();
}, [recommendations]);
额外优化点

原代码中useEffect里先调用fetchDataForRecommendations再执行setAnimeData([]),会导致先添加数据再清空,建议将setAnimeData([])放在请求逻辑之前,避免数据闪烁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 15:33:10