Дождитесь выполнения обещаний, прежде чем помещать их в массив (обещания Javascript)

#javascript #reactjs #firebase #asynchronous #google-cloud-storage

#javascript #reactjs #firebase #асинхронный #google-облачное хранилище

Вопрос:

Приветствую разработчиков Javascript

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

Мой компонент

 useEffect(() => {
    firebase
        .firestore()
        .collection('artworks')
        .doc(props.artworkid)
        .collection('images')
        .get()
        .then(images => {

            let arr = []

            images.docs.forEach(image => {

                arr.push({
                    thumbnail: getImageURL(`${ image.data().imagename }_200x200.${ image.data().imageextension }`),
                    fullres: getImageURL(`${ image.data().imagename }_2000x2000.${ image.data().imageextension }`)
                })

            })

        })
}, [ props.artworkid ])
  

Моя вспомогательная функция

 export const getImageURL = (filename) => {
    return firebase
        .storage()
        .ref(filename)
        .getDownloadURL()
        .then(response => {

            return response

        })
}
  

Проблема в том, что я всегда получаю массив, полный обещаний, которые выполняются позже:

 [{
    "thumbnail": Promise,
    "fullres": Promise
}, {
    "thumbnail": Promise,
    "fullres": Promise
}, {
    "thumbnail": Promise,
    "fullres": Promise
}, {
    "thumbnail": Promise,
    "fullres": Promise
}]
  

Я намерен заполнить массив объектов (URL-адреса миниатюр и полных изображений, хранящиеся в облачном хранилище Google Firebase) и отобразить его в виде галереи изображений в этом функциональном компоненте.

Как я могу дождаться выполнения обещаний, прежде чем помещать их в массив или состояние? Я думаю, это как-то связано с async / await… но я не могу понять это. Есть ли кто-нибудь, кто может мне помочь?

Реакция / Код Javascript

Комментарии:

1. Не ждите обещаний перед нажатием. Помещайте их в массив обещаний, а затем просто используйте Promise.all .

Ответ №1:

Вы, вероятно, хотите посмотреть Promise.all

 useEffect(() => {
    firebase
        .firestore()
        .collection('artworks')
        .doc(props.artworkid)
        .collection('images')
        .get()
        .then(images => {

            let arr = []

            images.docs.forEach(image => {
                const thumbnailPromise = getImageURL(`${ image.data().imagename }_200x200.${ image.data().imageextension }`)

                const fullresPromise = getImageURL(`${ image.data().imagename }_2000x2000.${ image.data().imageextension }`)

                Promise.all([thumbnailPromise, fullresPromise])
                    .then(values => {
                        arr.push({
                            thumbnail: values[0],
                            fullres: values[1]
                        })
                    });
            })

        })
}, [ props.artworkid ])
  

Комментарии:

1. Вот и все! Это было так просто. Теперь я также знаю, что мне нужно глубже погрузиться в асинхронное программирование с обещаниями. Спасибо!