GeoFire geoQuery возвращает данные

0

Я новичок в Firebase + GeoFire, и у меня проблемы с функцией запроса geoFire.

Я хочу добавить в массив результаты из функции geoQuery и вернуть ее в функцию. Но данные, которые я манипулирую внутри метода geoQuery.on выглядят вне видимости или недоступны или из-за обещаний, я не знаю... факт находится вне метода geoquery.on, продавцы переменных пустые.

Как я могу вернуть результаты из geoQuery и сохранить его в возвращаемой переменной

//Set seller position in firebase db
var setPosition = function() {
    navigator.geolocation.getCurrentPosition(setPositionSuccess, error, options);
    //navigator.geolocation.watchPosition(setPositionSuccess, positionError, { enableHighAccuracy:true })
};  

//Get sellers near buyer position
var getSellersForCurrentPosition = function() {
    navigator.geolocation.getCurrentPosition(getPositionSuccess, error, options);
    //navigator.geolocation.watchPosition(positionSuccess, positionError, { enableHighAccuracy:true })
};  


//Callback function from html 5 geo api
function getPositionSuccess(pos) {

    var crd = pos.coords;
    var currentPosition = [crd.latitude, crd.longitude];

    // Query radius
    var radiusInKm = 2;

    var firebaseRef = new Firebase(FBURL + "/geofire/sellers/");
    var geoFire = new GeoFire(firebaseRef);

    var geoQuery = geoFire.query({
        center: currentPosition,
        radius: radiusInKm
    }); 

    var sellers = []; 
    var oneSeller = {}; 

    var onKeyEnteredRegistration = geoQuery.on("key_entered", function(key, location, distance) {
        oneSeller = { 
            id: key,
            distance: distance,
            location: location
        };  
        sellers.push(oneSeller);
    }); 

    var onReadyRegistration = geoQuery.on("ready", function() {
          geoQuery.cancel();
    });

    return sellers;

} 

Кстати, насколько точна геолокация html5? Различие между браузером рабочего стола и мобильным браузером?

Теги:
firebase
geofire
angularfire

1 ответ

0

Geofire контролирует продавцов в указанном вами диапазоне. В любое время, когда продавец входит/выходит из диапазона, он запускает key_entered или key_exited. Эти события могут произойти в любое время после запуска запроса. В условиях JavaScript это часто описывается как: обратные вызовы происходят асинхронно.

Простой поток событий может объяснить, что происходит лучше всего:

  1. вы вызываете getPositionSuccess()
  2. вы запускаете Geoquery для мониторинга продавцов, находящихся в зоне действия: geoFire.query()
  3. никакие продавцы не находятся в зоне действия, поэтому ваш обратный вызов не срабатывает
  4. getPositionSuccess() функция getPositionSuccess() и завершается
  5. продавец входит в ассортимент
  6. GeoFire запускает событие key_entered и выполняет обратный вызов
  7. но getPositionSuccess() уже вышел, так как он может вернуть значение?

Даже если вы должны были дождаться, когда первый продавец войдет в диапазон до возвращения (возможно, в браузере, но это возможно в других языках/средах), как вы вернете значение, когда второй продавец входит в диапазон?

По этой причине вам приходится иметь дело с асинхронными данными по-разному. Обычно вы делаете это, перемещая код, который вызовет getPositionSuccess() в функцию.

Скажите, что вы сейчас пытаетесь это сделать:

var sellers = getPositionSuccess(pos);
sellers.forEach(function(seller) {
  addSellerToMap(seller);
});

Чтобы обрабатывать асинхронный характер событий, вы переместите этот код в getPositionSuccess:

//Callback function from html 5 geo api
function getPositionSuccess(pos) {
    var crd = pos.coords;
    var currentPosition = [crd.latitude, crd.longitude];

    // Query radius
    var radiusInKm = 2;

    var firebaseRef = new Firebase(FBURL + "/geofire/sellers/");
    var geoFire = new GeoFire(firebaseRef);

    var geoQuery = geoFire.query({
        center: currentPosition,
        radius: radiusInKm
    }); 

    var oneSeller = {}; 

    geoQuery.on("key_entered", function(key, location, distance) {
        oneSeller = { 
            id: key,
            distance: distance,
            location: location
        };  
        addSellerToMap(oneSeller);
    }); 
} 

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

  • 0
    Спасибо за Ваш ответ. Сначала я имею дело со статическими продавцами, чтобы сделать это проще, но идея в том, что они находятся в движении, поэтому я буду использовать метод watchPosition html5 geo api. Итак, допустим, у меня есть узел с продавцами и их позициями, которые обновляются в базе данных Firebase. Затем покупатель делает запрос, html5 api занимает свою текущую позицию, а geoQuery показывает продавцов, которые закрылись. Я не буду добавлять их на карту, просто получить их удостоверения личности. Поэтому мне нужно вернуть массив. Спасибо и извините за мой английский: {
  • 0
    Все звучит как совершенно правильный вариант использования. Но, к сожалению: современная сеть в целом и Firebase в частности носят асинхронный характер. Вы не можете синхронно возвращать данные, которые загружены асинхронно. Все, что вы можете сделать, это обновить центральное местоположение и затем сообщить об этом коду, который должен знать об обновленных данных. Так что там, где написано addSellerToMap вы также можете поместить tellBuyerThatASellerWasFound .
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню