GeoFire geoQuery返回数据

时间:2015-07-19 09:53:07

标签: angularjs firebase angularfire geofire

我是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地理定位有多准确?桌面浏览器和移动浏览器有什么不同吗?

1 个答案:

答案 0 :(得分:0)

Geofire 监控您指明范围内的卖家。每当卖家进入/退出该范围时,它都会触发key_enteredkey_exited事件。启动查询后,可以随时发生这些事件。在JavaScript术语中,这通常被描述为:回调发生异步

简单的事件流程可能会解释最佳情况:

  1. 您致电getPositionSuccess()
  2. 开始 Geoquery以监控范围内的卖家:geoFire.query()
  3. 没有卖家立即在范围内,因此您的回叫不会触发
  4. getPositionSuccess()功能已完成并退出
  5. 卖家进入范围
  6. GeoFire会触发key_entered事件并且您的回调会运行
  7. getPositionSuccess()已退出,那么它如何返回值?
  8. 即使您在返回之前等待第一个卖家进入范围(在浏览器中不可能,但 可能在其他语言/环境中),您将如何返回值当第二个卖家进入范围时?

    因此,您必须以不同方式处理异步数据。通常,您可以通过将调用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);
        }); 
    } 
    

    据我所知,在您的用例中,您的卖家不会移动,因此将它们视为静态列表可能更直观。但即使在这种情况下,结果也是从远程数据库加载的,并且在加载数据之前需要一些时间。现代Web以异步方式加载数据,所有代码都必须以类似于上面概述的方式处理它。