将一系列图片上传到 Firebase 存储



我正在尝试将一组图像上传到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,该承诺在以下情况下实现 作为可迭代对象传递的所有承诺都已实现

.....

返回的承诺通过一个数组来实现,该数组包含作为参数传递的可迭代对象的所有值(也是非承诺值(。

由于您的updateImage()函数是异步函数,因此您可以向Promise.all()传递对该函数的"调用"数组(上面提到的"可迭代"(,该数组基于imageArray生成,该数组是image对象数组(与您传递给updateImage()函数的image对象完全相同(。

因此,您可以执行以下操作:

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);

基本上,这里的问题是您需要单独上传每张图片。不存在"捆绑"上传或类似内容。

正常方法

这种 propblem 的基本方法是遍历数组(此处是图像数组imgArr(并单独上传每个项目。
这样的函数可以如下所示:

for (i = 0; i < imgArr.length; i++) {
this.updateImage(imgArr[i]);
}

或使用 forEach 方法:

imgArr.forEach((img) => {
this.updateImage(img);
}

切记: 函数this.updateImage在原始代码中提供。

如果是异步函数,例如上传,获取数据或其他此方法不起作用。这是由JS的实现引起的,并且无法等待for(Each(循环中的操作。

该解决方案附带asyncForEach。asyncForEach 函数执行异步任务(上传图像(并等待它完成。

实现的工作方式如下(详情如下(:

  1. 将函数 asyncForEach 添加到代码中
  2. 上传数组时调用函数 asyncForEach

实现要实现
异步上传,请执行以下操作:
.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);
}
}

然后调用新实现的函数,使用以下代码
行调用它(注意:变量"imgArr"表示要上传的图像数组(:

// 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()

资源来源

  • MDN forEach
  • 实施 1
  • 实施 2
  • JS中的循环

最新更新