如何等待 Firebase 存储图像上传,然后运行下一个函数
Posted
技术标签:
【中文标题】如何等待 Firebase 存储图像上传,然后运行下一个函数【英文标题】:How to wait for Firebase storage image upload, then run next function 【发布时间】:2020-07-09 14:47:56 【问题描述】:我正在尝试编写一个函数,将多个图像上传到 Firebase,保存返回到对象的 URL,然后将该对象上传到我的 Cloud Firestore。我对 async/await 或 Promise 并没有真正的了解,所以如果有人可以提供帮助,将不胜感激。
基本上,我希望uploadImages()
完成运行,然后运行uploadData()
,其中saveIssue()
在提交表单时被触发。
这是我正在使用的:
saveIssue()
this.uploadImages();
this.uploadData();
,
uploadData()
let self = this;
db.collection("issues")
.add(self.issue)
.then(docRef =>
self.$router.push(
name: "ReportPage",
params: issueId: docRef.id
);
)
.catch(error =>
console.error(error);
);
,
uploadImages()
const storageRef = storage.ref();
let self = this;
this.imagePreviews.forEach(image =>
let imageName = uuidv1();
let fileExt = image.fileName.split(".").pop();
let uploadTask = storageRef
.child(`images/$imageName.$fileExt`)
.putString(image.base64String, "data_url");
uploadTask.on("state_changed",
error: error =>
console.error(error);
,
complete: () =>
uploadTask.snapshot.ref.getDownloadURL().then(downloadURL =>
self.issue.images.push(downloadURL);
);
);
);
,
【问题讨论】:
【参考方案1】:你必须使用 Promise,正如 here 解释的那样。你可以重写你的代码来支持异步等待,因为firebase支持它开箱即用,但一开始它可以是这样的:
async saveIssue()
await this.uploadImages();
await this.uploadData();
,
uploadData()
return new Promise((resolve, reject) =>
let self = this;
db.collection("issues")
.add(self.issue)
.then(docRef =>
self.$router.push(
name: "ReportPage",
params:
issueId: docRef.id
);
resolve();
)
.catch(error =>
console.error(error);
reject(error);
);
)
,
uploadImages()
return new Promise((resolve, reject) =>
const storageRef = storage.ref();
let self = this;
this.imagePreviews.forEach(image =>
let imageName = uuidv1();
let fileExt = image.fileName.split(".").pop();
let uploadTask = storageRef
.child(`images/$imageName.$fileExt`)
.putString(image.base64String, "data_url");
uploadTask.on("state_changed",
error: error =>
console.error(error);
reject(error);
,
complete: () =>
uploadTask.snapshot.ref.getDownloadURL().then(downloadURL =>
self.issue.images.push(downloadURL);
resolve();
);
);
);
)
,
【讨论】:
好的,这似乎是一个好的开始。它适用于 for each 中的第一个循环,但不适用于其余循环。有什么见解吗? 你需要查看 Promise.all,在这里阅读所有 async/await 的内容:javascript.info/async-await - 你基本上必须创建多个 Promise,然后一个一个地运行它 感谢您的回答。是否可以不创建此处所述的新承诺 (***.com/a/55806234/144088) 但仍监控上传状态?【参考方案2】:好的,我找到了基于@AlexBrohshtut's answer 的解决方案。我仍然有一个问题,即第一个循环完成将允许等待继续,下面的代码似乎解决了这个问题。如果有人有更简洁的答案,很高兴更新! (我充其量是中级...)
saveIssue()
Promise.all(
this.imagePreviews.map(async image =>
return await this.uploadImages(image);
)
).then(() =>
this.uploadData();
);
,
uploadData()
let self = this;
db.collection("issues")
.add(self.issue)
.then(docRef =>
self.$router.push(
name: "ReportPage",
params:
issueId: docRef.id
);
)
.catch(error =>
console.error(error);
);
,
uploadImages(image)
const storageRef = storage.ref();
let self = this;
return new Promise((resolve, reject) =>
let imageName = uuidv1();
let fileExt = image.fileName.split(".").pop();
let uploadTask = storageRef
.child(`images/$imageName.$fileExt`)
.putString(image.base64String, "data_url");
uploadTask.on("state_changed",
error: error =>
console.error(error);
reject(error);
,
complete: () =>
uploadTask.snapshot.ref.getDownloadURL().then(downloadURL =>
self.issue.images.push(downloadURL);
resolve();
);
);
);
【讨论】:
以上是关于如何等待 Firebase 存储图像上传,然后运行下一个函数的主要内容,如果未能解决你的问题,请参考以下文章
如何将图像上传到firebase存储然后将图像url存储在firestore中?