【问题标题】:GeoFire geoQuery returning dataGeoFire geoQuery 返回数据
【发布时间】:2015-10-08 14:23:14
【问题描述】:

我是 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 的地理位置有多准确?桌面浏览器和手机浏览器有区别吗?

【问题讨论】:

    标签: angularjs firebase angularfire geofire


    【解决方案1】:

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

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

    1. 你打电话给getPositionSuccess()
    2. 启动一个地理查询来监控范围内的卖家: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);
        }); 
    } 
    

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

    【讨论】:

    • 感谢您的回答。起初,我与静态卖家打交道更容易,但想法是他们在移动,所以我将使用 watchPosition html5 geo api 方法。所以,假设我有一个节点,其中有卖家,他们的位置在 firebase db 中更新。然后,买家提出请求,html5 api 获取其当前位置,geoQuery 显示已关闭的卖家。我不会在地图上添加他们,只是获取他们的 ID。所以我需要返回一个数组。感谢和抱歉我的英语:{
    • 所有听起来都是一个完全有效的用例。但不幸的是:现代网络,特别是 Firebase,本质上是异步的。您不能同步返回异步加载的数据。您所能做的就是更新一个中心位置,然后让需要了解更新数据的代码知道它。所以在上面写着addSellerToMap的地方你也可以写上tellBuyerThatASellerWasFound
    • 您必须掌握异步编程。对于一个在稍微不同的上下文中涵盖它的好答案:stackoverflow.com/questions/27049342/…。对于与 Firebase 无关但同样相关的入门读物,请阅读:stackoverflow.com/questions/14220321/…
    • 感谢您的回复和链接,但我认为我的问题更容易。查看此链接中的第一个答案,groups.google.com/forum/#!topic/firebase-talk/VUdy5yAhN1k 这正是我想要的,但是在 geoQuery.on 方法之外,sellers 变量是空的,我们应该使用 $scope 变量吗?在 geoQuery.on("ready", callback) 我得到了 Sellers 变量,但我需要返回以在 SellerCtrl 控制器中加载 $scope.sellers 变量
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-10
    • 1970-01-01
    相关资源
    最近更新 更多