Как я могу выполнить запрос без ожидания в React?

# #jquery #reactjs #firebase #google-cloud-firestore

Вопрос:

Я пытаюсь понять, как работает запрос, и я видел этот пример:

 const citiesRef = db.collection('cities');
const snapshot = await citiesRef.where('capital', '==', true).get();
if (snapshot.empty) {
  console.log('No matching documents.');
  return;
}  

snapshot.forEach(doc => {
  console.log(doc.id, '=>', doc.data());
});
 

Проблема в том, что когда я пытаюсь сделать что-то подобное в своем реальном коде, я получаю ошибку компиляции, основанную на ожидании вот печать

введите описание изображения здесь

и вот мой код

 const librosRef = db.collection('libros');
    const queryRef = librosRef.where('grado', '==', '4° Grado');

    const snapshot = await queryRef.get();
    
    if (snapshot.empty) 
    {
        console.log('No matching documents.');
        return;
    }  
    
    snapshot.forEach(doc => 
    {
        console.log(doc.id, '=>', doc.data());
  });
 

Есть ли способ сделать это без ожидания ? Я не расширяю (может быть проблема) Я просто кодирую простые функции, есть ли для этого какие-то обходные пути ?

Редактировать: Я также пробовал следующее, но это тоже не работает

 //relevant code
useEffect(() => {
        db.collection("libros")
        .orderBy("precio")
        .where('grado', '==', '4° Grado')
        .get()
        .then((snapshot) => {
              const tempData = [];
            snapshot.forEach((doc) => {
              const data = doc.data();
              tempData.push(data);
    
              console.log(doc.data());
              console.log("Temp Data: ", tempData);
            });
            setLibros(tempData);
          });
      }, []);

//relevant code so it makes sense what is printing
<tbody>
                {libros.map((e) => (
                        
                        <tr >
                        <td>

                        <input onChange = {(event) => {
                            let checked = event.target.checked;
                        }} 
                        
                        type="checkbox" checked = "">
                        </input>
                        </td>
                        <td>{e.grado}</td>
                        <td >{e.descripcion}</td>
                        <td >{e.editorial}</td>
                        <td >${parseFloat(e.precio).toFixed(2)}</td>
                        </tr>
                     ))}
                </tbody>
 

Вот что он печатает

введите описание изображения здесь

И вот как это выглядит в firebase

введите описание изображения здесь

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

1. Чтобы использовать await, ваша функция должна быть async функцией. Кроме того, вы можете заменить await на a .then(value => { /*...*/ }) . Проверьте Promise методы или посмотрите какой-нибудь учебник по обработке обещаний

2. да, я пробовал .then(значение…и т. Д.), Но это тоже не сработало, я пойду проверю методы обещания и проверю некоторые учебные пособия, иногда трудно найти учебные пособия, если я не знаю правильного названия материала, просто поймите, что существуют методы «Обещания».

3. await ждет Promise объект. Это «почти» то же самое, что добавить then() к нему а и асинхронно его ждать. Но для того, чтобы это работало, эта функция должна быть async function() {} . Асинхронная функция возвращает Promise тоже. Это большая тема. Проверьте эту страницу, я думаю, что она очень полная. Не уверен, что это хорошая точка входа, подумал: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…

4. Также помните, что .then() не выполняется синхронно. Без an await он будет выполнен позже, когда запрос к базе данных завершится. Что касается вашего редактирования, если вы добавляете журнал в самом начале then() , он что-то регистрирует?

5. В фактическом журнале я просто понял, что он печатал следующее (не проверял, потому что я картофелина) Uncaught (in promise) FirebaseError: The query requires an index . что именно вы хотите, чтобы я зарегистрировал ? Это queryRef ?

Ответ №1:

Вы можете сделать что-то подобное, просто изменив useEffect :

 useEffect(() => {
  (async () => {
    const response = await db.collection("libros")
      .orderBy("precio")
      .where('grado', '==', '4° Grado')
      .get();
    
    const tempData = [];
    response.forEach((doc) => {
      const data = doc.data();
      tempData.push(data);
      
      console.log(doc.data());
      console.log("Temp Data: ", tempData);
    });
    setLibros(tempData);
  })();
}, []);

 

В принципе, мы используем IIFE, useEffect чтобы иметь возможность использовать асинхронность.

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

1. По какой-то причине это не работает, вместо этого это дало мне ошибку Uncaught (in promise) FirebaseError: The query requires an index.

2. Эта ошибка также должна содержать ссылку, которую вы можете использовать для создания требуемого индекса.

3. Это первый раз, когда я вижу это, и я понятия не имею, что это такое, я собираюсь быстро проверить это, спасибо за помощь!