异步/等待上传任务

Posted

技术标签:

【中文标题】异步/等待上传任务【英文标题】:Async/Await uploadTask 【发布时间】:2019-04-08 21:57:36 【问题描述】:

如何等待 uploadTask,以便在将下载 url 和文档插入到 firestore 之前先上传图像/文件并跟踪其进度,

以下代码是我的示例 Vue 项目。可以正常使用,但是看if (portraitFile),必须在必须上传图片的情况下,不想上传图片怎么办?

它必须移出条件if,但它会在文件完成和检索到的下载 URL 之前异步执行。

目标:将 firestore add() 移到 uploadTask 的完成回调/参数之外。

    async commitCharacter() 
      try 
        let character = this.character;
        let portraitFile = this.portraitFile;

        if (portraitFile) 
          const uploadTask = storageRef
            .child(`characters/$character.id/portrait.png`)
            .put(portraitFile,  contentType: "image/png" );

          await uploadTask.on(
            "state_changed",
            snapshot => 
              this.portraitUploadProgress =
                (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
            ,
            null,
            async () => 
              character.portraitUrl = await storageRef
                .child(`characters/$character.id/portrait.png`)
                .getDownloadURL();

              if (character.id) 
              await db
                .collection("characters")
                .doc(character.id)
                .update(character);
               else 
                character.id = (await 
                db.collection("characters").add(character)).id;
              

              $("#manageCharacter").modal("hide");
            
          );
        
      

【问题讨论】:

【参考方案1】:

您可以将uploadTask 包装在一个承诺中:

async function uploadTaskPromise() 
  return new Promise(function(resolve, reject) 
    const storageRef = storage.ref(YOUR_STORAGE_PATH)
    const uploadTask = storageRef.put(YOUR_FILE_OR_BLOB)
    uploadTask.on('state_changed',
      function(snapshot) 
        var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100
        console.log('Upload is ' + progress + '% done')
      ,
      function error(err) 
        console.log('error', err)
        reject()
      ,
      function complete() 
        uploadTask.snapshot.ref.getDownloadURL().then(function(downloadURL) 
          resolve(downloadURL)
        )
      
    )
  )

然后像这样使用它:

const storageUrl = await uploadTaskPromise()
console.log(storageUrl) // do whatever you want with the URL...

【讨论】:

以上是关于异步/等待上传任务的主要内容,如果未能解决你的问题,请参考以下文章

“异步任务然后等待任务”与“任务然后返回任务”[重复]

异步/等待和任务

异步等待返回任务

运行多个异步任务并等待它们全部完成

异步调用 WCF 服务并在新任务中等待它

AppDomain 等待异步任务防止 SerializationException