【问题标题】:Waiting until image finishes upload to fire code等到图像完成上传到触发代码
【发布时间】:2022-01-21 00:19:09
【问题描述】:

我正在努力强制代码同步。该代码旨在使用 vue 可组合上传图像,等待上传成功,然后将 url 从 firebase 存储存储到数据库中。我能做的最好的就是让代码正常工作,但成功代码在上传完成之前触发(虽然我得到了 url)。

下面的代码不起作用,但我尝试使用 then 回调将动作链接在一起,以强制它们以同步方式运行。不工作。

VueComponent.vue

const newImage = async () => {
      if (image.value) {
        await uploadImage(image.value);
      } else return null;
    };

    const handleSubmit = async () => {
     
      try {
      
        const colRef = collection(db, "collection");

        newImage()
          .then(() => {
            addDoc(colRef, {
              content: content.value
            });
          })
          .then(() => {
            //code to run only on success
              });
          });
       
      } catch (error) {
       
      }
    };

useStorage.js 可组合

import { ref } from "vue";
import { projectStorage } from "../firebase/config";
import {
  uploadBytesResumable,
  getDownloadURL,
  ref as storageRef,
} from "@firebase/storage";

const useStorage = () => {
  const error = ref(null);
  const url = ref(null);
  const filePath = ref(null);

  const uploadImage = async (file) => {
    filePath.value = `${file.name}`;

    const storageReference = storageRef(projectStorage, 
 filePath.value);

  //<--I want this to be synchronous, but it isn't.
    const uploadTask = uploadBytesResumable(storageReference, 
 file);

    uploadTask.on(
      "state_changed",
      (snapshot) => {
        const progress =
          (snapshot.bytesTransferred / snapshot.totalBytes) * 
 100;
        console.log("Upload is " + progress + "% done");
      },
      (err) => {
       
  
      },
      () => {
    getDownloadURL(uploadTask.snapshot.ref).then((downloadURL) 
     => 
        {console.log("File available at", downloadURL);
      });
      }
    );
    
  };


  return { url, filePath, error, uploadImage };
};

export default useStorage;

【问题讨论】:

  • “我正在努力强制代码异步。”您现在已经多次说过这句话,并且:1) 您可能的意思是强制它为 同步,2) 使异步代码同步是不可能的。它始终是异步的。
  • “不工作”和“不工作”真的很难帮助。代码在运行时做什么?你期望它做什么?如果你在每一行都设置了一个断点,然后在调试器中运行,这是 first 行,它不会像你预期的那样工作。
  • 谢谢你,@FrankvanPuffelen。你说得对,我的意思是“同步”。当handleSubmit 触发时,newImage() 函数触发但不等待uploadTask 完成,所以它直接进入addDoc()。我希望在 addDoc 开始之前完成 uploadTask。

标签: javascript vue.js google-cloud-firestore firebase-storage


【解决方案1】:

您的uploadImage 不会等待上传完成,这就是为什么addDoc 发生的时间比您希望的要早。

const uploadImage = async (file) => {
  filePath.value = `${file.name}`;

  const storageReference = storageRef(projectStorage, 
filePath.value);

  const uploadTask = uploadBytesResumable(storageReference, 
file);

  await uploadTask; // ? Wait for the upload to finish

  const downloadURL = getDownloadURL(uploadTask.snapshot.ref)

  return downloadURL;
}

现在你可以调用它:

newImage()
  .then((downloadURL) => {
    addDoc(colRef, {
      content: content.value
    });
  })

或者,通过再次使用await,与:

const downloadURL = await newImage();
addDoc(colRef, {
  content: content.value
});

【讨论】:

  • 一如既往,非常感谢!那行得通。我将使用此代码。我被绊倒了,因为我正在使用uploadTask.on,我收到一个错误,它不是一个函数。我删除了 .on 代码,这很好,并且可以正常工作。我无法从谷歌文档中得知 .on 导致该错误的原因。
  • 由于您在调用代码中使用了then(),因此您必须返回来自newImage 的承诺,而您没有这样做。您可以使用on,但在这种情况下,您需要返回自己的承诺(return new Promise((resolve, reject) =&gt; {,然后在获得下载 URL 后调用 resolve()
  • 好东西。非常感谢您的时间
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-24
  • 2021-12-02
  • 1970-01-01
  • 2012-06-08
  • 2015-07-14
相关资源
最近更新 更多