как ждать разрешения обещания в методе array.map? - PullRequest
0 голосов
/ 31 октября 2019

Я хочу загрузить фотографии в хранилище Firebase.

В состоянии компонента React у меня есть массив с фотографиями. Фотографии - это файлы, которые пользователь просматривает при вводе файлов. Фотографии имеют свойство .needUpload до true, если файл необходимо загрузить в хранилище.

Вот функция загрузки:

uploadPhotos = () => {
    let photosToSave = []
    if (this.state.photos.length) {
      photosToSave = this.state.photos
        .filter(photo => photo.needUpload && true)
        .map(photo => {
          const extensionPattern = /(?:\.([^.]+))?$/
          const fileName = photo.value.name
          const fileExtension = extensionPattern.exec(fileName)[1]
          const newFileName = new Date().getTime()
          const fileLocation = storageRef.child('estateObjects/' + newFileName + '.' + fileExtension)

          return new Promise(resolve => {
            fileLocation.put(photo.value).on(
              firebase.storage.TaskEvent.STATE_CHANGED,
              snapshot => {
                //let progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100
              },
              null,
              () => {
                fileLocation.getDownloadURL().then(url => {
                  resolve({ url: url, file: newFileName + '.' + fileExtension })
                })
              }
            )
          })
        })
      return Promise.all(photosToSave).then(response => {
        return response
      })
    } else return Promise.all(photosToSave).then(response => [])
  }

Основная проблема заключается в том, что когда начинается загрузка, она (терпеливо) жду, я думаю для загрузки сначала 2-3 файла, затем в массиве 'resolve' я получаю дублированные элементы массива. Так что-то работает не так, но я не могу понять, что ...

может быть, проблема с новым именем файла ?? Когда файл переименовывает новый Date.getTime () возвращает одно и то же время для нескольких файлов, потому что они были загружены одновременно?

enter image description here

Ответы [ 3 ]

1 голос
/ 31 октября 2019

цикл карты выполняется очень быстро, поэтому время между итерациями не изменится

Итак, я предлагаю вам использовать index, чтобы гарантировать уникальность имени файла

uploadPhotos = () => {
  let photosToSave = [];

  if (this.state.photos.length) {
    photosToSave = this.state.photos.filter(photo => photo.needUpload && true).map((photo, index) => {
      const extensionPattern = /(?:\.([^.]+))?$/;
      const fileName = photo.value.name;
      const fileExtension = extensionPattern.exec(fileName)[1];
      const newFileName = `${new Date().getTime()}_${index}`;
      const fileLocation = storageRef.child('estateObjects/' + newFileName + '.' + fileExtension);
      return new Promise(resolve => {
        fileLocation.put(photo.value).on(firebase.storage.TaskEvent.STATE_CHANGED, snapshot => {//let progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100
        }, null, () => {
          fileLocation.getDownloadURL().then(url => {
            resolve({
              url: url,
              file: newFileName + '.' + fileExtension
            });
          });
        });
      });
    });
    return Promise.all(photosToSave).then(response => {
      return response;
    });
  } else return Promise.all(photosToSave).then(response => []);
}
0 голосов
/ 31 октября 2019

Я думаю, что альтернатива для добавления синхронного метода в newFileName может работать.

var time = ''; //Global variable
function getTime() {
   if(new Date().getTime() === time){return getTime()}
   else time = new Date().getTime();
   return time;
}
0 голосов
/ 31 октября 2019

Я запустил это на консоли и вот результат, догадываясь, что может быть проблемой.

 [...Array(7).keys()].map(v=> console.log(new Date().getTime()))

VM676:2 1572510011727
VM676:5 1572510011728

Существует библиотека uuid с нулевой зависимостью, которую вы можете использовать для проверки уникальности имен файлов здесь

npm install uuid

const uuidv1 = require('uuid/v1');
uuidv1(); // ⇨ '2c5ea4c0-4067-11e9-8bad-9b1deb4d3b7d'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...