问题
I want to write a query function which returns an object. The problem is, in my case the function returns undefined.
var filterDataAccordingToDate = function (ref, startTime, endTime) {
var filteredObj = {};
ref.orderByChild('date').startAt(startTime).endAt(endTime)
.once('value', function(snap) {
filteredObj = snap.val();
console.log(util.inspect(filterDataAccordingToDate(filteredObj, false, null));
//Returns the correct object
return filteredObj;
});
}
console.log("DATA RETURNED: " + util.inspect(filterDataAccordingToDate(travelRef, 1466439004, 1466439011), false, null));
// DATA RETURNED: undefined
回答1:
As Ami mentions, you can't return a result from an asynchronous call.
What you could do is process your results using a method and simply call your asynchronous call directly without expecting a return result:
var filterDataAccordingToDate = function (ref, startTime, endTime) {
ref.orderByChild('date').startAt(startTime).endAt(endTime)
.once('value', function(snap) {
var filteredObj = snap.val();
console.log(util.inspect(filterDataAccordingToDate(filteredObj, false, null));
doSomethingWith(filteredObj);
});
}
function doSomethingWith(obj) {
console.log("DATA RETURNED: " + util.inspect(obj, false, null));
}
filterDataAccordingToDate(travelRef, 1466439004, 1466439011);
I suppose it all depends on what you want to do with your data and how many times you wish to reference it.
Note: I do suggest placing your script in a self-contained function to avoid adding private functions (specific to a single piece of functionality) so that you don't pollute your global namespace. Ben Alman wrote a nice post about Immediately-Invoked Function Expressions (IIFE) or you can make use of a JavaScript namespace.
Edit: As adolfosrs suggests, you can also use promises but keep in mind what browsers you wish to support.
回答2:
I would go with a Promise.
var filterDataAccordingToDate = function (ref, startTime, endTime) {
var filterDataAccordingToDatePromise = new Promise( function(resolve, reject) {
ref.orderByChild('date').startAt(startTime).endAt(endTime).once('value', function(snap) {
filteredObj = snap.val();
resolve(filteredObj);
});
});
return filterDataAccordingToDatePromise;
};
filterDataAccordingToDate(travelRef, 1466439004, 1466439011).then(function(result){
//this callback will be trigger when firebase call finish.
//result is what you set on the resolve.
console.log("DATA RETURNED: " + util.inspect(result, false, null));
});
回答3:
The problem is that Firebase uses an asynchronous listeners to a database reference, hence you can't return from the callback.
You can store the return objects into your dictionary inside the callback.
来源:https://stackoverflow.com/questions/37927555/firebase-query-function-returns-undefined