我有一个 forEach
函数,它循环遍历一组文件,将文件上传到 Firebase 存储,然后在上传之后,它将图像引用链接存储到之前定义的数组中。
每次迭代的过程:
- 获取文件对象并转换为 Blob
- 将 Blob 上传到 Firebase
- Blob 上传后,接收回调,其中包含上传的图像引用
- 将图像引用存储在列表中
在 forEach
之后,我使用图像引用列表进行进一步处理。 但是,当我尝试引用该列表时,它通常是空的,因为此代码在任何图像上传之前执行(并且未收到引用)。我如何将 async/await 与 Javascript forEach 函数结合使用,在其中我可以调用我的代码以等待它应该期望填充的图像引用列表。我已经尝试在 stackoverflow 上找到解决方案,但对我的解决方案没有帮助。
submitPost = async event => {
event.preventDefault();
const img_names = [];
this.state.files.forEach((ref_, index) => {
ref_.current.getCroppedCanvas().toBlob(blob => {
var uploadTask = this.storageRef
.child("images/" + String(index))
.put(blob);
uploadTask.on(
"state_changed",
snapshot => {
var progress =
(snapshot.bytesTransferred / snapshot.totalBytes) * 100;
console.log("Upload is " + progress + "% done");
},
error => {
console.log(error);
},
() => {
img_names.push(uploadTask.snapshot.ref.toString());
}
);
});
console.log(img_names) // empty here
});
最佳答案
您可以使用 map
而不是 forEach
来实现该功能。将您的数组转换为 promise 数组。然后在 Promise.all()
中使用该数组并等待它。
const promisifyUpload = (storageRef, ref_, index) => {
return new Promise((resolve, reject) => {
ref_.current.getCroppedCanvas().toBlob(blob => {
var uploadTask = storageRef
.child("images/" + String(index))
.put(blob);
uploadTask.on(
"state_changed",
snapshot => {
var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
console.log("Upload is " + progress + "% done");
},
error => console.log(error),
() => resolve(uploadTask.snapshot.ref.toString())
);
});
});
};
const submitPost = async event => {
event.preventDefault();
const img_names = await Promise.all(
this.state.files.map((ref_, index) => promisifyUpload(this.storageRef, ref_, index))
));
console.log(image_names); // Should now be filled
});
编辑:我将它分成 2 个函数以显示隔离“promisify”逻辑
关于javascript - 仅在 Javascript forEach/map 之后执行代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59057613/