Firebase Promise возвращает неопределенные данные Javascript

Я следовал нескольким руководствам о том, как правильно ожидать данные из моей функции ListFile(). Я записал вывод на консоль в ListFile(), поэтому знаю, что данные верны. Когда я пытаюсь дождаться завершения функции и регистрации данных, я получаю один из двух результатов при экспериментировании с ожиданиями и обещаниями:

getData error: TypeError: undefined is not an object (evaluating 'response.json')

или

Promise {
  "_U": 0,
  "_V": 0,
  "_W": null,
  "_X": null,
}

Я создаю приложение React Native, и функция, которая вызывает ListFile(), содержит кучу других компонентов, которые отображаются, поэтому я не могу сделать всю функцию асинхронной. Не знаю, что еще здесь делать.

Вызывает ListFile()

const getData = async () => {
    try {
        const response = await ListFile();
        const data = response.json();
        console.info(data);
    } catch (err) {
        console.info("getData error: " + err);
    }
}

getData(); //always returns getData error: TypeError: undefined is not an object (evaluating 'response.json')

СписокФайл()

async function ListFile() {
    // Reference Firebase Container
    var filesInStorageList = [];
    let content = [];
    const listRef = ref(fbStorage, filePath);
    console.info("Listing Files");


    // List all files in container
    listAll(listRef)
        .then((res) => {
            res.prefixes.forEach((folderRef) => {
                // All the prefixes under listRef.
                // You may call listAll() recursively on them.
                console.info(res);
            });
            res.items.forEach((itemRef) => {
                // All the items under listRef.
                let fileInStorage = itemRef["_location"]["path_"].slice(filePath.length);
                filesInStorageList.push(fileInStorage);
                // CORRECT DATA IS LOGGED console.info("Pushing " + fileInStorage);
                // CORRECT DATA IS LOGGED console.info(filesInStorageList);
            });

            return filesInStorageList;
        }).catch((error) => {
            // Uh-oh, an error occurred!
            console.info("ListFile - ERROR");
        });
}
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
46
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы смешиваете async/await и Promises. Хотя они служат схожим целям, обычно они используются по отдельности, чтобы избежать подобных ситуаций, когда они используются вместе, а затем создают неожиданные результаты, если не знать, на что обращать внимание.

Вы аннотируете свою функцию ListFile с помощью async, что означает, что она ожидает где-то найти await. Вместо этого вы используете основанные на промисах .then и .catch.

Чтобы преобразовать ваш код, вы можете изменить его на это:

async function ListFile() {
    // Reference Firebase Container
    var filesInStorageList = [];
    let content = [];
    const listRef = ref(fbStorage, filePath);
    console.info("Listing Files");

    // List all files in container
    try {
      const res = await listAll(listRef);
      //...do your forEach loops
      return filesInStorageList;
    } catch(err) {
      //handle your error
    }
}

Это сработало, я также обновил свой файл getData. Спасибо!

Paulie 16.03.2022 14:04

Чтобы уточнить и убедиться, что я понимаю, должен ли я не вносить никаких изменений в getData? Когда я оставляю все как есть, ответ остается неопределенным.

Paulie 17.03.2022 06:05

Что вы имеете в виду под «ответ остается неопределенным»? Нет, не обязательно менять. Но имейте в виду, что, как написано в вашем вопросе, он не возвращает значение и не устанавливает какое-либо состояние.

jnpdx 17.03.2022 06:12

Вы должны добавить return к методу listAll, чтобы возвращать его значение при вызове из getData(). См. пример кода ниже:

  const getData = async () => {
      try {
          ListFile()
          .then((response) => {
            // do something here.
            console.info(response);
          });

      } catch (err) {
          console.info("getData error: " + err);
      }
  }
  
  getData();

  async function ListFile() {
    // Reference Firebase Container
    var filesInStorageList = [];
    let content = [];
    const filePath = "test/";
    const listRef = ref(storage, filePath);

    // List all files in container
    return listAll(listRef)
        .then((res) => {
            res.prefixes.forEach((folderRef) => {
                // All the prefixes under listRef.
                // You may call listAll() recursively on them.
                console.info(res);
            });
            res.items.forEach((itemRef) => {
                // All the items under listRef.
                let fileInStorage = itemRef["_location"]["path_"].slice(filePath.length);
                filesInStorageList.push(fileInStorage);
                // CORRECT DATA IS LOGGED console.info("Pushing " + fileInStorage);
                // CORRECT DATA IS LOGGED console.info(filesInStorageList);
                // console.info(filesInStorageList);
                
            });

            return filesInStorageList;
        }).catch((error) => {
            // Uh-oh, an error occurred!
            console.info(error);
        });
}

Кроме того, как заявил @jnpdx, вы должны использовать .then и .catch на основе Promise на своем ListFile()

Является ли return filesInStorageList; правильным, хотя теперь возвращается весь listAll(listRef)?

Paulie 16.03.2022 13:47

@Поли, да. есть также return filesInStorageList;, который затем вернет fileInStorage, помещенный в массив filesInStorageList. Это один из обходных путей для вашего варианта использования.

Marc Anthony B 16.03.2022 14:41

Другие вопросы по теме