Javascript 如何等待Firebase存储映像上载,然后运行下一个函数
我正在尝试编写一个函数,将多个图像上载到Firebase,保存返回到对象的URL,然后将该对象上载到我的云Firestore。我对async/await或Promissions并不是很了解,所以如果有人能帮忙,我将不胜感激 基本上,我希望uploadImages完成运行,然后运行uploadData,在提交表单时激发saveIssue 以下是我的工作内容:Javascript 如何等待Firebase存储映像上载,然后运行下一个函数,javascript,firebase,vue.js,promise,firebase-storage,Javascript,Firebase,Vue.js,Promise,Firebase Storage,我正在尝试编写一个函数,将多个图像上载到Firebase,保存返回到对象的URL,然后将该对象上载到我的云Firestore。我对async/await或Promissions并不是很了解,所以如果有人能帮忙,我将不胜感激 基本上,我希望uploadImages完成运行,然后运行uploadData,在提交表单时激发saveIssue 以下是我的工作内容: saveIssue() { this.uploadImages(); this.uploadData(); }, uploadDat
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);
});
}
});
});
},
正如所解释的,你必须使用承诺。您可以重写代码以支持异步等待,因为firebase支持开箱即用,但一开始可以是这样: 异步存储问题{ 等待这个。上传图片; 等待这个。上传数据; }, 上传数据{ 返回新的PromiseSolve,拒绝=>{ 让自我=这个; db.collectionissues .addself.issue .thendocRef=>{ self.$router.push{ 名称:ReportPage, 参数:{ issueId:docRef.id } }; 决定 } .catcherror=>{ 控制台错误; 拒绝错误; }; } }, 上传图像{ 返回新的PromiseSolve,拒绝=>{ const storageRef=storage.ref; 让自我=这个; this.imagePreviews.forEachimage=>{ 让imageName=uuidv1; 让fileExt=image.fileName.split..pop; 让uploadTask=storageRef .child`images/${imageName}.${fileExt}` .putStringimage.base64字符串,数据\u url; uploadTask.onstate_已更改{ 错误:错误=>{ 控制台错误; 拒绝错误; }, 完成:=>{ uploadTask.snapshot.ref.getDownloadURL.thendownloadURL=>{ self.issue.images.pushdownloadURL; 决定 }; } }; }; }
},如前所述,您必须使用承诺。您可以重写代码以支持异步等待,因为firebase支持开箱即用,但一开始可以是这样: 异步存储问题{ 等待这个。上传图片; 等待这个。上传数据; }, 上传数据{ 返回新的PromiseSolve,拒绝=>{ 让自我=这个; db.collectionissues .addself.issue .thendocRef=>{ self.$router.push{ 名称:ReportPage, 参数:{ issueId:docRef.id } }; 决定 } .catcherror=>{ 控制台错误; 拒绝错误; }; } }, 上传图像{ 返回新的PromiseSolve,拒绝=>{ const storageRef=storage.ref; 让自我=这个; this.imagePreviews.forEachimage=>{ 让imageName=uuidv1; 让fileExt=image.fileName.split..pop; 让uploadTask=storageRef .child`images/${imageName}.${fileExt}` .putStringimage.base64字符串,数据\u url; uploadTask.onstate_已更改{ 错误:错误=>{ 控制台错误; 拒绝错误; }, 完成:=>{ uploadTask.snapshot.ref.getDownloadURL.thendownloadURL=>{ self.issue.images.pushdownloadURL; 决定 }; } }; }; }
},好的,我找到了一个基于的解决方案。我仍然有一个问题,第一个循环完成将允许等待继续,下面的代码似乎解决了这个问题。如果有人有更简洁的答案,欢迎更新!我充其量只是中等
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();
});
}
});
});
}
好的,我找到了一个基于的解决方案。我仍然有一个问题,第一个循环完成将允许等待继续,下面的代码似乎解决了这个问题。如果有人有更简洁的答案,欢迎更新!我充其量只是中等
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();
});
}
});
});
}
好吧,这似乎是个好的开始。它适用于for each中的第一个循环,但不适用于其余循环。有什么见解吗?你需要看看Promise。总之,在这里阅读所有async/await内容:-你基本上必须创建多个Promise,然后逐个运行它以获得答案。是否可以不创建此处所述的新承诺,但仍监视上载状态?好的,这似乎是一个好的开始。它适用于for each中的第一个循环,但不适用于其余循环。有什么见解吗?你需要看看Promise。总之,在这里阅读所有async/await内容:-你基本上必须创建多个Promise,然后逐个运行它以获得答案。是否可以不创建此处所述的新承诺,但仍监视上载状态?