我有一组图像,正在将这些图像上载到firebase存储.

      data = {
        ...data,
        downloadedUrl: [],
      };
    
      if (data?.image?.length) {
        for (const image of data?.image) {
          await uploadFile(image, data);
        }
      }

uploadFile处理将图像上载到firebase的逻辑.

  const uploadFile = useCallback((file, data) => {
    if (!file) return;

    const storageRef = ref(storage, `/images/${file.name}`);
    const uploadTask = uploadBytesResumable(storageRef, file);

    uploadTask.on(
      "state_changed",
      (snap_shot) => {},
      (err) => console.log(err),
      async () => {
        await getDownloadURL(uploadTask.snapshot.ref).then((url) => {
          data.downloadedUrl.push(url);
        });
      }
    );
  }, []);

It takes few seconds to get the downloadedUrl from uploadTask and I want to store this downloadedUrl in firebase firestore when I get all the urls.

Issue with the current approach is that before getting the urls, the other function start executing and I am not able to upload this data on firestore with the downloadedUrl Here's the full function when someone clicks on form submit

const handleFormSubmit = useCallback(
    async (data) => {
      setLoading(true);
      data = {
        ...data,
        downloadedUrl: [],
      };

      if (data?.image?.length) {
        for (const image of data?.image) {
          await uploadFile(image, data);
        }
      }

      if (data.downloadedUrl.length) {
        uploadDataToFirestore(data);
      }
 
      if (!data.downloadedUrl?.length) {
        dispatch(handleAlertState({ message: "Error Occured!!!" }));
        router.push("/services");
        return;
      }
      setLoading(false);
      router.push("/");
    },
    [dispatch, router, uploadDataToFirestore, uploadFile]
  );

  const uploadDataToFirestore = useCallback(
    async (data) => {

      await setDoc(doc(db, "form-responses"), data)
        .then((response) => {
          console.log("response", response);
          dispatch(
            handleAlertState({
              message: "Success. Your request has been sent. Thank You.",
            })
          );
        })
        .catch((error) => {
          console.log("error", error);
        });
    },
    [dispatch]
  );

下面的代码块在图像上载到云存储时执行代码.

      if (!data.downloadedUrl?.length) {
        dispatch(handleAlertState({ message: "Error Occured!!!" }));
        router.push("/services");
        return;
      }

推荐答案

  1. 创建promise 数组
  2. Promise.all来观察每个promise

const uploadFile = useCallback((file, data) => {
  return new Promise((resolve, reject) => {
    if (!file) reject();

    const storageRef = ref(storage, `/images/${file.name}`);
    const uploadTask = uploadBytesResumable(storageRef, file);

    uploadTask.on(
      'state_changed',
      snap_shot => {},
      err => reject(err),
      () => resolve(getDownloadURL(uploadTask.snapshot.ref)),
    );

  });
}, []);

let allPromises = [];
if (data?.image?.length) {
  for (const image of data?.image) {
    allPromises.push(uploadFile(image, data));
  }
}

let uploadedUrls = await Promise.all(allPromises);
console.log(uploadedUrls);

Javascript相关问答推荐

无法检测卡片重叠状态的问题

我的角模板订阅后不刷新'

我创建了一个创建对象的函数,我希望从该函数创建的对象具有唯一的键.我怎么能做到这一点?

如何通过将实例方法的名称传递给具有正确类型的参数的继承方法来调用实例方法?

为什么JPG图像不能在VITE中导入以进行react ?

MarkLogic-earch.suggest不返回任何值

AJAX POST在控制器中返回空(ASP.NET MVC)

无法读取未定义的属性(正在读取合并)-react RTK

OnClick更改Json数组JSX中的图像源

在Java脚本中录制视频后看不到曲目

如果对象中的字段等于某个值,则从数组列表中删除对象

Angel Auth Guard-用户只有在未登录时才能访问登录页面,只有在登录时才能访问其他页面

有角粘桌盒阴影

AstroJS混合模式服务器终结点返回404

已在EventListener中更新/更改异步的React.js状态对象,但不会导致组件重新呈现

使用JavaScript或PHP从div ID值创建锚标记和链接

webpack 5和mini-css-extract-plugin在将scss保存到css文件后不加载css

我不能将每个产品单独添加或删除到Collection 列表中

无法从fixture 文件中提取数据

当你点击数组时,如何在相应的元素中输出?