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

如何等待Firebase Storage多图上传完成并获取全部下载URL?

解决Firebase Storage批量上传后等待所有下载URL收集完成的问题

我有一个图片数组,点击按钮后将每张图片单独上传至Firebase Storage,并把下载URL存入一个数组。希望所有图片上传完成后展示该数组,但遇到问题:在Promise.all处断点时,数组里只能看到部分(比如5张里的前3张)URL,只有刷新浏览器后才能看到剩余的。如何确保等待所有下载URL真正存入数组后再执行后续操作?

const uploadAllImages = async () => {
let array = [];
const promises = [];
try {
  for (let i = 0; i < previews.length; i++) {
    const fileName = uuidv4() + ".jpg";
    const storageRef = ref(
      storage,
      `${currentUser.email}/images/` + fileName
    );

    const filesForUpload = await uploadString(
      storageRef,
      previews[i],
      "data_url"
    ).then((snapshot) => {
      getDownloadURL(snapshot.ref).then(async (url) => {
        array.push(url);
      });
    });

    promises.push(filesForUpload);
  }
} catch (error) {
  console.log(error);
}

await Promise.all(promises)
  .then(() => {
    console.log(array);
    setUploadedImages(array);
  })
  .then(() => //Set to true elsewhere  setLoading(false));
};

问题根源

你的代码里,getDownloadURL的异步操作没有被纳入Promise.all的等待队列。uploadString的then回调只触发了getDownloadURL,但没有返回这个Promise,导致filesForUpload实际上是uploadString完成后的undefined。Promise.all只等待了上传操作结束,却没等所有下载URL的获取操作完成,所以此时array还没收集全所有URL。

修复后的代码

const uploadAllImages = async () => {
  try {
    // 用Promise.all直接收集所有URL,无需手动维护数组
    const uploadedUrls = await Promise.all(previews.map(async (preview) => {
      const fileName = uuidv4() + ".jpg";
      const storageRef = ref(
        storage,
        `${currentUser.email}/images/${fileName}`
      );
      // 先完成上传,再获取下载URL,返回该URL
      const snapshot = await uploadString(storageRef, preview, "data_url");
      return getDownloadURL(snapshot.ref);
    }));

    console.log(uploadedUrls);
    setUploadedImages(uploadedUrls);
    setLoading(false);
  } catch (error) {
    console.log(error);
    // 出错时也记得关闭loading
    setLoading(false);
  }
};

关键优化点

  • 用Array.map替代for循环,直接生成包含每个「上传+获取URL」的Promise数组,代码更简洁。
  • 每个Promise链完整包含uploadString和getDownloadURL,确保Promise.all等待所有异步操作完成后,直接得到完整的URL数组。
  • 移除手动维护array的逻辑,避免异步操作顺序导致的数组填充不完整问题。
  • 统一处理错误,确保无论成功失败都能关闭loading状态。

内容的提问来源于stack exchange,提问作者Captai-N

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 02:48:10