因此,我具有以下功能,该功能将处于状态的所有照片uris上载到firebase存储中,然后将状态为uris替换为上载图片时生成的firebase下载网址:
uploadImages = async (userID) => {
//loop through every image
for (var index = 0; index < this.state.images.length; index++) {
//convert image uri to blob
const response = await fetch(this.state.images[index]);
const blob = await response.blob();
//upload image to firebase
let refer = firebase.storage.ref().child('images/' + userID + '/image' + (index + 1));
refer.put(blob)
.then((snapshot) => {
snapshot.ref.getDownloadURL().then((downloadURL) => {
//update image url in state
let images = this.state.images
images[index] = downloadURL
this.setState({images: images});
});
})
.catch((error) => {
alert(error);
});
}
}
我想做的是调用另一个函数updateData,它将所有状态的信息上载到Firebase数据库。问题是,我要在所有图片都已上传并且所有下载URL都处于状态之后执行此操作。我尝试在for循环之后简单地调用该函数,但这似乎不起作用,因为.put()是异步的,因此for循环在图片上传之前和下载URL处于状态之前完成。然后我尝试了这个:
.then((snapshot) => {
snapshot.ref.getDownloadURL().then((downloadURL) => {
//update image url in state
let images = this.state.images
images[index] = downloadURL
this.setState({images: images});
//call updateData when the last picture has been uploaded
if (index === (this.state.images.length - 1)){
this.updateData(userID);
}
});
})
但是这也不起作用,因为到.then中的回调函数被调用时,循环已经运行了,并且索引已经比this.state.images.length +1。那么有没有办法做到这一点?我希望在最后一个图像上传后仅一次调用updateData。
答案 0 :(得分:1)
如果您有多个需要等待的承诺,请将它们全部收集到一个数组中并使用Promise.all()
,将其传递给该数组,这将返回一个新的Promise,只有在数组中的所有Prom解决。