Как заставить это ... цикл останавливаться и ждать, прежде чем продолжить? (JavaScript async / await со слушателем Firestore) - PullRequest
0 голосов
/ 07 мая 2019

Эта функция обрабатывает массив слов. Если он находит слово в нашем словаре, он переходит к следующему слову. Если он не находит слово в нашем словаре, он записывает запрос слова в нашу базу данных Firestore. Затем он устанавливает прослушиватель, который прослушивает запись слова «ответ» в базу данных Firebase. Когда ответ написан, слушатель отсоединяется. Это займет около двух секунд. Этот код перебирает массив слов, не дожидаясь ответа слова. Как мне сказать ему дождаться ответа слова, прежде чем перейти к следующему слову?

$scope.requestWords = function() {

  async function processWordRequests() {
    for (let word of $scope.wordsArray) {
      console.log(word);
      var doc = await firebase.firestore().collection('Dictionaries').doc($scope.longLanguage).collection("Words").doc(word).get()
      if (doc.data() === undefined) {
        console.log("Didn't find " + word + " in L2 dictionary.");

        await firebase.firestore().collection('Users').doc($scope.user.uid).collection($scope.longLanguage).doc('Word_Request').set({
          word: word,
          requestOrigin: $scope.longLanguage + ':' + $scope.movieTitle + ':' + $scope.clipInMovieModel
        })
        console.log("Requested " + word);

        await firebase.firestore().collection('Users').doc($scope.user.uid).collection($scope.longLanguage).doc('Word_Response').onSnapshot(function(doc) {
          console.log("Listening for response...");
          if (doc.data().word === word) {
            console.log(word + " added to L2 dictionary.");
            firebase.firestore().collection('Users').doc($scope.user.uid).collection($scope.longLanguage).doc('Word_Response')
            .onSnapshot(function (){
              console.log("Listener unsubscribed.")
              // How do I make it wait here before going on to the next word?
              return;
            });
          }
          else {
            console.log("Still listening...")
          }
        });

      } else {
        console.log("Found " + word + " in L2 dictionary.");
      }
    }
  }

  processWordRequests();
};

1 Ответ

1 голос
/ 07 мая 2019

Вам нужно использовать обещания или обещать свой код.

У вас есть эта строка кода:

    await firebase.firestore().collection('Users').doc($scope.user.uid).collection($scope.longLanguage).doc('Word_Response').onSnapshot(function(doc) {

Который путь справа, (используйте разрывы строк, чтобы улучшить читаемость) у вас есть .onSnapshot(function(doc) {, который я точно не знаю, но я собираюсь догадаться, что он не возвращает обещание, поэтому вы не можете его ждать.

Вместо этого вы можете обернуть егообещание как ...

await new Promise((resolve, reject)=> {
    firebase.firestore().collection('Users').doc($scope.user.uid).collection($scope.longLanguage).doc('Word_Response').onSnapshot(function(doc) {
    ...
    resolve("value-to-return-to-await").
    ...
});

Вы можете узнать больше об обещаниях с помощью этого автономного учебного курса: https://github.com/stevekane/promise-it-wont-hurt

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...