I have a forEach
function that loops through an array of files, uploads the file to Firebase Storage and then after the upload, it stores the image reference link into a array defined before.
Process of each iteration:
After the forEach
, I use the list of image references for further processing. However, when I try and reference the list, it is usually empty because this code executes before any images upload (and references are not recieved). How can I use async/await with a Javascript forEach function where I can invoke my code to wait where it should expect a populated image reference list . I've already tried to find a solution on stackoverflow but hasn't helped toward my solution.
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
});
You can achieve that functionality by using map
instead of forEach
. Convert your array into an Array of Promises. Then use that array inside a Promise.all()
and await it.
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
});
Edit : I split it up into 2 functions to show isolate the "promisify" logic
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.