Загрузка массива изображений в хранилище Firebase - PullRequest
0 голосов
/ 09 января 2020

Я пытаюсь загрузить массив изображений в хранилище 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]
            });
          }
        }

Ответы [ 2 ]

1 голос
/ 09 января 2020

Вы можете использовать Promise.all(). Как объяснено в do c:

Метод Promise.all() возвращает одно обещание, которое выполняется, когда все обещания, переданные как итеративные, были выполнены

... ..

Возвращенное обещание выполняется с массивом, содержащим все значения повторяемого аргумента, передаваемого в качестве аргумента (также значения без обещаний).

Поскольку ваша функция updateImage() asyn c one, вы можете передать Promise.all() массив «вызовов» к этой функции («повторяемый», упомянутый выше), который вы генерируете на основе imageArray, который является массивом image Objects ( точно такой же 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);
    });
})

Или в асинхронной функции c:

const urlsArray = await updateImageArray(imageArray);
0 голосов
/ 09 января 2020

В основном проблема заключается в том, что вам нужно загружать каждое изображение самостоятельно. Загрузка пакета или подобный файл не существует.

Обычный подход

Подход базового c к такой проблеме будет заключаться в цикле по массиву (здесь массив изображений imgArr) и загружать каждый элемент индивидуально.
Такая функция может выглядеть следующим образом:

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

или с помощью метода forEach:

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

Помните : функция this.updateImage предоставляется в исходном коде.

В случае асинхронной функции, такой как загрузка, выборка данных или другие, этот подход НЕ работает. Это вызвано реализацией JS и тем фактом, что невозможно выполнить операцию внутри for (Each) l oop.

Решение поставляется с 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()

Ресурсы

...