0

我是 Firebase + GeoFire 的新手,我在使用 geoFire 查询功能时遇到了问题。

我想将 geoQuery 函数的结果添加到一个数组中,并在一个函数中返回它。但是我在geoQuery.on方法内部操作的数据似乎超出范围或不可用或由于承诺,我不知道......事实在 geoquery.on 方法之外,变量 Sellers 是空的。

如何从 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 的地理位置有多准确?桌面浏览器和移动浏览器有区别吗?

4

1 回答 1

0

Geofire监控您指定范围内的卖家。任何时候卖家进入/退出范围,它都会触发一个key_enteredorkey_exited事件。这些事件可能在您开始查询后随时发生。在 JavaScript 术语中,这通常被描述为:回调异步发生。

一个简单的事件流,可以解释最好的情况:

  1. 你打电话getPositionSuccess()
  2. 启动Geoquery 来监控范围内的卖家:geoFire.query()
  3. 没有卖家立即在范围内,因此您的回调不会触发
  4. 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);
    }); 
} 

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

于 2015-07-19T15:49:20.260 回答