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. 範囲内にある売り手を監視するジオクエリを開始します。geoFire.query()
  3. 範囲内にすぐに売り手がいないため、コールバックは発生しません
  4. getPositionSuccess()関数が完了して終了します
  5. 売り手が範囲内に来る
  6. GeoFire がkey_enteredイベントを発生させ、コールバックが実行されます
  7. しかし、getPositionSuccess()すでに終了しているので、どうすれば値を返すことができますか?

最初の売り手が範囲内に入るのを待ってから戻ったとしても (ブラウザで不可能ですが、他の言語/環境では可能です)、2 番目の売り手が範囲内に入ったときにどのように値を返しますか?

このため、非同期データを別の方法で処理する必要があります。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 はデータを非同期的にロードするため、すべてのコードは、上で概説したのと同様の方法でデータを処理する必要があります。

于 2015-07-19T15:49:20.260 に答える