我正在尝试将一系列图像上传到Firebase存储。我已经为单个图像上传编写了一个函数,并且该函数可以完美运行,但是我似乎无法全神贯注于如何实现图像数组上传。有人能指出我正确的方向吗?以下是我的示例,仅保留了相关部分
uploadAsync = async uri => {
const user = Firebase.auth.currentUser.uid;
const path = `users/${user}/images/${Math.round(
Math.random() * 1000000000
)}.jpg`;
return new Promise(async (res, rej) => {
const response = await fetch(uri);
const file = await response.blob();
const upload = Firebase.storage().ref(path).put(file);
upload.on(
'state_changed',
snapshot => {},
err => {
rej(err);
},
async () => {
const url = await upload.snapshot.ref.getDownloadURL();
res(url);
}
);
});
};
updateImage = async ({ image }) => {
const user = Firebase.auth.currentUser.uid;
for (let i = 0; i < image.length; i++) {
const file = image[i].image;
const remoteUri = await this.uploadAsync(file);
const firestoreRef = firebase.firestore().collection('Images').doc(user);
firestoreRef.set({
image: [remoteUri]
});
}
}
您可以使用Promise.all()
。如文档中所述:
Promise.all()
方法返回满足以下条件的单个Promise:通过迭代的所有诺言都实现了.....
返回的promise由包含作为参数传递的可迭代的所有值的数组(也包括非承诺值)实现。
由于Promise.all()
函数是一个异步函数,因此可以将基于updateImage()
生成的对该函数的“调用”数组(上述“可迭代”)传递给Promise.all()
imageArray
对象(与传递给image
函数的image
对象完全相同)。
因此您可以执行以下操作:
updateImage()
或在异步函数中:
const updateImageArray = async (imageArray) => {
return Promise.all(imageArray.map(item => updateImage(item)));
}
const imageArray = [....];
updateImageArray(imageArray).then(urls => {
urls.forEach(element => {
console.log(element);
});
})
基本上,这里的问题是,您需要自行上传每个图像。不存在“捆绑”上传或类似内容。
常规方法
解决此类问题的基本方法是在数组(此处为图像数组const urlsArray = await updateImageArray(imageArray);
)上循环并分别上传每个项目。这样的功能看起来像这样:
imgArr
或使用forEach方法:
for (i = 0; i < imgArr.length; i++) {
this.updateImage(imgArr[i]);
}
Remember:原始代码中提供了功能this.updateImage。
在异步功能(例如上载,数据获取或其他此方法不起作用的情况下)。这是由JS的实现引起的,事实上,for(Each)循环内的操作无法等待。
该解决方案随asyncForEach一起提供。 asyncForEach函数执行异步任务(上载图像)并等待它完成。
该实现的工作方式如下(详细信息如下:):>
实施
imgArr.forEach((img) => {
this.updateImage(img);
}
文件的上部添加以下功能。 :变量'imgArr'表示要上传的图像数组):.js
然后调用新实现的函数,并使用以下代码行对其进行调用(注
// implementation of asynchonous forEach // array: array of items to process // callback: the asynchonous function to process the items async asyncForEach(array, callback) { for (let index = 0; index < array.length; index++) { await callback(array[index], index, array); } }
资源
// create a function 'uploadArray' in which the asyncForEach is called.
const uploadArray= async () => {
await this.asyncForEach(imgArr, async (img) => {
await this.updateImage(img);
};
/* execute the function. The code following this function call will be
stalled until the images are either uploaded or failed with error
(implement error handling in the this.updateImage function
await uploadArray()