Требуется, чтобы второй запрос firebase запускался после завершения первого javascript

#javascript #firebase #firebase-realtime-database

#javascript #firebase #firebase-realtime-database

Вопрос:

Я новичок в javascript, и недавно я работал над проектом, и в этом проекте я пытаюсь сохранить начальный результат в пустой базе данных firebase, которая отлично работает. Однако, как только результат сохранен, я хочу получить его и выполнить некоторые вычисления на нем. Я пробовал setTimeout , но это не сработало. Кстати, если в firebase уже есть оценки, он работает нормально.

Это мой код и заранее спасибо:

 function resultOne() {
var firstScore = trim(newGroup[0]);

scores(firstScore);

setTimeout(function() {return true;}, 30000);
var firstguyScore = getScore(firstScore)
console.log(firstGuyScore);
}
  

Это функция для установки начального значения 1500 и set name….

 function scores(firstGuy) {
// Firebase query to increment the chosen girl and her seen status by 1 and to initialize each score by 1500
let ref = firebase.database().ref("scores");
let query = ref.orderByChild("name").equalTo(firstGuy);
query.once("value").then((snapshot) => {
  if (snapshot.exists()) {
    snapshot.forEach((userSnapshot) => {
      let userRef = userSnapshot.ref;
      userRef.child("chosen").transaction((currentValue) => {
        return currentValue   1;
      });

      userRef.child("seen").transaction((currentValue) => {
        return currentValue   1;
      });
    });
  }
  else {
    ref.push({
      name: firstGuy,
      chosen: 1,
      seen: 1,
      score: 1500
    });
  }
});
  

и это функция для восстановления данных

 async function getScore(firstGuy) {

  let ref = firebase.database().ref("scores");
  let query = ref.orderByChild("name").equalTo(firstGuy);
  const snapshot = await query.once("value")
    if (snapshot.exists()) {
      snapshot.forEach((userSnapshot) => {
        var userData = userSnapshot.val();
        score = userData.score;
        console.log(score);
      });
    }
  
}
  

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

1. once() возвращает обещание, я предлагаю использовать это вместо параметра обратного вызова в вашей функции scores, а также заставить scores возвращать обещание, которое разрешается после завершения работы.

Ответ №1:

setTimeout() вызывает функцию (обратный вызов), которую вы предоставляете, через определенное время. Он не блокируется и не ожидает. Ваш вызов getScores() выполняется немедленно, как вы можете видеть в консоли.

Вы можете изменить код следующим образом:

 function resultOne() {
  const firstScore = trim(newGroup[0]);

  scores(firstScore);

  setTimeout(() => {
    const firstguyScore = getScore(firstScore);
    console.log(firstGuyScore);
  }, 30000);
}
  

Использование setTimeout() этого способа подходит для тестирования и отладки. Вы не должны использовать его таким образом в своем готовом к производству коде.

Почему бы также не await включить scores() ?

 async function scores(firstGuy) {
  ...
  const snapshot = await query.once("value");
  ...
}

async function resultOne() {
  const firstScore = trim(newGroup[0]);
  await scores(firstScore);
  const firstguyScore = await getScore(firstScore);
  console.log(firstGuyScore);
}
 
  

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

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

2. Вы не должны использовать setTimeout() с произвольным таймаутом, потому что нет «правильного» таймаута. Время ожидания будет либо слишком большим, что приведет к потере времени, либо слишком коротким, что приведет к ошибкам. Использование Promises и async / await — это правильный путь.

3. Извините, но я новичок. Не могли бы вы немного помочь мне с обещаниями?

4. Я предлагаю вам прочитать или посмотреть введение или руководство по Promises, подобное этому . Если вы сталкиваетесь с конкретными проблемами, в StackOverflow обычно есть ответы, или вы можете опубликовать новый вопрос.