简体   繁体   English

完成后上传任务getDownloadUrl()

[英]upload task getDownloadUrl() after completion

I need this general purpose utility method that accepts the file object and return me the url of the file after uploading, but some how I am getting a promise instead of the download URL. I need this general purpose utility method that accepts the file object and return me the url of the file after uploading, but some how I am getting a promise instead of the download URL.

I have tried all approached, i need ES6 async/await solution.我已经尝试了所有方法,我需要 ES6 async/await解决方案。

export const uploadFile = (file) => {
  let uploadTask = storage.ref(`products/${Date.now()}.${file.name.split('.').pop()}`).put(file);
  uploadTask.on(firebase.storage.TaskEvent.STATE_CHANGED, {
    'complete': () => {
      uploadTask.snapshot.ref.getDownloadURL().then((d) => {
        return d
      })
    }
  });
}

As explained in the doc, if you call then() on a UploadTask , you will get an object which "behaves like a Promise, and resolves with its snapshot data when the upload completes".如文档中所述,如果您在UploadTask上调用then() ,您将获得一个 object ,其“行为类似于 Promise,并在上传完成时使用其快照数据解析”。

Therefore the following should do the trick.因此,以下应该可以解决问题。

export const uploadFile = (file) => {
  let uploadTask = storage.ref(`products/${Date.now()}.${file.name.split('.').pop()}`).put(file);
  return uploadTask.
    then(snapshot => {
      return snapshot.ref.getDownloadURL();
    })
    .then((url) => {
      return url
    });
}

Update following your comment:根据您的评论更新:

You mention in the comments that you call the function as follows:您在评论中提到您将 function 称为如下:

let files = state.images; 
for (let i = 0; i < e.target.files.length; i++) { 
   files = files.concat(e.target.files[i]); 
   let url = uploadFile(files[i])
   console.log(url)
}

However, the uploadFile() function is asynchronous and indeed, as a consequence, it returns a Promise.然而, uploadFile() function是异步的,因此实际上它返回了 Promise。 You should take that into account when calling it.调用它时应该考虑到这一点。 For example, with a loop, you could call it as follows:例如,使用循环,您可以按如下方式调用它:

const promises = [];
let files = state.images; 
for (let i = 0; i < e.target.files.length; i++) { 
   files = files.concat(e.target.files[i]); 
   promises.push(uploadFile(files[i]));
}
Promise.all(promises)
 .then(urlsArray => {
    urlsArray.forEach(url => {
        console.log(url);
    })
  })

ES6 async await solution for others having similar problem: ES6 async await 其他有类似问题的解决方案:

export const uploadFile = async (file) => {
  let uploadTask = storage.ref(`products/${Date.now()}.${file.name.split('.').pop()}`).put(file);
  const snapshot = await uploadTask;
  const url = await snapshot.ref.getDownloadURL();
  return url;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM