2016-06-20 2 views
1

Я хочу написать функцию запроса, которая возвращает объект. Проблема в том, что в моем случае функция возвращает undefined.Функция запроса Firebase возвращает 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 

ответ

3

Как Ami упоминает, вы не можете вернуть результат от асинхронного вызова.

Что вы можете сделать, это обрабатывать результаты, используя метод и просто вызвать ваш асинхронный вызов непосредственно, не ожидая результата возврата:

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); 

Я полагаю, все это зависит от того, что вы хотите сделать с вашими данными и сколько раз вы хотите ссылаться на него.

Примечание: Я предлагаю разместить ваш скрипт в автономной функции, чтобы не добавлять частные функции (специфичные для одной части функциональности), чтобы вы не загрязняли ваше глобальное пространство имен. Ben Alman написал хороший пост о вымышленных выражениях (IIFE) или вы можете использовать JavaScript namespace.

Редактировать: Как adolfosrs предполагает, вы можете также использовать promises, но имейте в виду, что browsers вы хотите поддержать.

2

Проблема заключается в том, что Firebase использует асинхронные слушатель к ссылке базы данных, поэтому вы не можете вернуться из обратного вызова.

Вы можете сохранить возвращаемые объекты в свой словарь внутри обратного вызова.

2

Я бы пошел с обещанием.

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)); 
}); 
Смежные вопросы