Rewrite synchronous firebase function to asynchronous

时间:2018-03-25 20:53:13

标签: javascript mysql firebase firebase-realtime-database

I'm used to work with Mysql, and usually I do something like this:

function foo(userId){
 $gender = getGender($userId); 
 //getGender returns result of SQL query: SELECT gender FROM users WHERE uid = $userId
return $gender;
}

This approach doesn't work with Firebase, since it's asynchronous. I know I could do something like this:

ref.child(userId +'/gender').once('value').then(function(snap => {
 doSomethingWithGender(snap.val());
});

However, since I'm using functions with two or more arguments, which are results of database queries, this approach doesn't cut it. Is there a way to pass asynchronous functions to a function, wait until they are fulfilled, and then execute the function?

More specifically, I want to achieve something like this:

function compareUsers(u1,u2){
  var totalScore = 0;
  var n = countAnswers(u1,u2);
  for(i = 1 ; i <= n ; i++){
    var weight = compare(getResponse(u1, i), getResponse(u2, i));
totalScore = totalScore + weight;
}
  var score = totalScore/n;
  console.log(score);
}
function countAnswers(u1,u2){
  var dimension = getMin(getMaxKey(u1), getMaxKey(u2));
}
function getMaxKey(uID){
  var ref = db.ref("score/" + uID);
  return ref.orderByChild('id').limitToLast(1).once("value").then(snap => {
    return snap.key;
  });
}
function getResponse(uID, qID){
  var ref = db.ref("answer/" + uID + "/" + qid);
    return ref.child('answer').once("value").then(snap => {
      return snap.val();
  });
}

1 个答案:

答案 0 :(得分:0)

What you're looking for is Promise.all(). Firebase's once() method returns a promise, and Promise.all() resolves (i.e. calls its then() method once all promises you give it are resolved).

So:

Promise.all([getMaxKey(u1), getMaxKey(u2)]).then(function(keys) {
  console.log(keys[0], keys[1]);
});