Handling Asynchronous Calls (Firebase) in functions
You nailed the two possibilities: Either make your function asynchronous as well, or cache the latest Firebase data so you can access it synchronously. Which one you use is just a matter of preference and convenience, given the context of the app you're writing.
For instance, we've noticed that "action games" are usually driven by a tight render loop instead of by firebase data change events. So it makes sense to cache the latest Firebase data for use in your render loop. For example:
var latestSnapshot = null;
firebaseRef.on('value', function(snap) { latestSnapshot = snap; });
And then you can use latestSnapshot synchronously in your render loop (or wherever else), though you need to be careful to deal with it being null until the first firebase callback happens.
Same idea as in the answer @Kato provided, but with the built-in promises in Firebase would look something like this
function calcVelocity(snapshot) {
var distance, time, velocity;
distance = snapshot.val().distance;
time = snapshot.val().time;
return distance / time;
}
function getVelocity() {
return firebaseRef.once('value').then(calcVelocity);
}
getVelocity().then(function(vel) { $("#velocity").html(vel); });
Another approach is to utilize a Promise strategy. jQuery has a great one.
function calcVelocity() {
var distance, time, velocity, def = $.Deferred();
firebaseRef.once('value', function(snapshot) {
distance = snapshot.val().distance;
time = snapshot.val().time;
def.resolve( distance / time );
});
return def.promise();
}
calcVelocity().then(function(vel) { $("#velocity").html(vel); });
Keep in mind also that snapshot.val().distance;
may return an error if snapshot.val()
returns null!