我是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地理定位有多准确?桌面浏览器和移动浏览器有什么不同吗?
答案 0 :(得分:0)
Geofire 监控您指明范围内的卖家。每当卖家进入/退出该范围时,它都会触发key_entered
或key_exited
事件。启动查询后,可以随时发生这些事件。在JavaScript术语中,这通常被描述为:回调发生异步。
简单的事件流程可能会解释最佳情况:
getPositionSuccess()
geoFire.query()
getPositionSuccess()
功能已完成并退出key_entered
事件并且您的回调会运行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);
});
}
据我所知,在您的用例中,您的卖家不会移动,因此将它们视为静态列表可能更直观。但即使在这种情况下,结果也是从远程数据库加载的,并且在加载数据之前需要一些时间。现代Web以异步方式加载数据,所有代码都必须以类似于上面概述的方式处理它。