Как решить неправильное возвращаемое значение функции javascript + firebase из-за того, что порядок операций отличается при получении данных? - PullRequest
1 голос
/ 19 июня 2019

В настоящее время я реализую функцию javascript, чтобы судить, совпадают ли идентификатор пользователя и имя.

function name_match(user_id, user_realname) {
    var dbref = firebase.database().ref();
    var namesref = dbref.child("names");
    namesref.on("value", function(snapshot) {
        snapshot.forEach(i => {
            if(i.key == user_id && i.child("realname").val() == user_realname) {
                return true;
            }
        });
    });
    return false;
}

Однако, независимо от ввода, он первоначально вернет false. Я думаю, что это потому, что он будет возвращать «ложь» во время загрузки данных Firebase.

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

function name_match2() {
    var user_id = document.getElementById("user-id").value;
    var user_realname = document.getElementById("user-realname").value;
    if(!name_match(user_id, user_realname)) return -1;
    return 0;
}

И он вернет -1.

Можете ли вы объяснить, как решить эту проблему?

Ответы [ 2 ]

3 голосов
/ 19 июня 2019

Как объяснил Дэниел в комментарии, внешняя функция никогда не возвращает true.Асинхронные решения могут быть следующими:)

function name_match(user_id, user_realname) {
    return new Promise(function (resolve, reject) {
      var dbref = firebase.database().ref();
      var namesref = dbref.child("names");
      namesref.on("value", function(snapshot) {
          var matched = false;
          snapshot.forEach(i => {
              if(i.key == user_id && i.child("realname").val() == user_realname) {
                  matched = true;
              }
          });

          if (matched) {
             resolve()
          } else {
             reject()
          }
      });
    });
}

На другой стороне вызывающей функции

name_match('userId', 'userName').then(function(){
//matched
}, function(){
//unmatched
}); 

Другой способ - использовать обратные вызовы:

function name_match(user_id, user_realname, cb) {
      var dbref = firebase.database().ref();
      var namesref = dbref.child("names");
      namesref.on("value", function(snapshot) {
          var matched = false;
          snapshot.forEach(i => {
              if(i.key == user_id && i.child("realname").val() == user_realname) {
                  matched = true;
              }
          });

          cb(matched);
    });
}

В этом случае:

name_match('userId', 'userName', function(matched) {
    console.log(matched);
})
0 голосов
/ 19 июня 2019

Вот небольшая адаптация решения Suryapratap с использованием метода once(), который

  1. "прослушивает ровно одно событие указанноготипа события, а затем прекращает прослушивание. ", и
  2. Возвращает Promise

... вместо использования метода on(), который устанавливает слушателя.

function name_match(user_id, user_realname) {

      var dbref = firebase.database().ref();
      var namesref = dbref.child("names");

      return namesref.once('value').then(function(snapshot) {
          var matched = false;
          snapshot.forEach(i => {
              if(i.key == user_id && i.child("realname").val() == user_realname) {
                  matched = true;
              }
          });
          return matched;
      });

}
...