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

从Firebase获取存储文件时如何避免点击标签重复展示已加载内容

问题根因

现有去重逻辑失效核心是getDownloadURL为异步接口:短时间重复点击触发多次函数调用时,第一批请求的回调还未执行、图片URL还未写入allImages数组,第二批请求的去重判断就已经完成,会同时命中indexOf(url) === -1的条件,最终导致重复插入数据。

修复方案

通过三层逻辑规避重复渲染问题:

  • 新增加载状态锁,避免同时间段重复触发请求
  • 新增已加载路径缓存,已经拉取完成的路径不再重复发起请求
  • 用Promise.all批量处理异步下载地址请求,统一完成后再更新数据,进一步避免并发导致的重复问题
完整修改后代码

首先新增必要的状态变量(以React为例,其他框架可对应实现同类状态):

// 加载状态锁
const [isLoading, setIsLoading] = useState(false);
// 已完整加载的存储路径缓存,可根据业务需求决定是否保留
const [loadedPaths, setLoadedPaths] = useState(new Set());

const getFromFirebase = (forceRefresh = false) => {
    const currentPath = `${user1}/${currentItem.id}`;
    // 前置校验:正在加载中,或 该路径已加载且非强制刷新场景,直接终止执行
    if (isLoading || (loadedPaths.has(currentPath) && !forceRefresh)) return;

    setIsLoading(true);
    const storageRef = storage.ref(currentPath);
    
    storageRef.listAll()
      .then(res => {
        // 批量生成所有图片下载地址的异步请求
        const urlPromises = res.items.map(imageRef => 
          imageRef.getDownloadURL().then(url => ({
            Test: url,
            Test2: imageRef.name
          }))
        )
        // 等待所有异步请求完成
        return Promise.all(urlPromises)
      })
      .then(imageList => {
        // 统一去重后更新图片列表
        setImages(prev => {
          const existUrlSet = new Set(prev.map(item => item.Test));
          const filterNewImages = imageList.filter(img => !existUrlSet.has(img.Test));
          return [...prev, ...filterNewImages];
        })
        // 标记当前路径已完成加载
        setLoadedPaths(prev => new Set(prev).add(currentPath));
      })
      .catch(error => {
        console.log(error);
      })
      .finally(() => {
        // 无论请求成功失败都释放加载锁
        setIsLoading(false);
      });
};
可选补充逻辑

如果需要切换currentItem时自动重置状态,可添加监听逻辑:

useEffect(() => {
  // 切换资源项时重置加载状态,可根据业务需要决定是否清空已加载的图片列表
  setIsLoading(false);
}, [currentItem.id])

如果仅需要避免短时间重复点击、不需要缓存已加载路径,删除loadedPaths相关的校验和更新逻辑即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 07:36:03