2015-12-01 2 views
1

Я новичок в GeoFire, FireBase и Angular. Я пытаюсь создать функцию, которая примет некоторые координаты и вернет некоторые объекты в окрестности этих координат.координация событий geoFire Ready и key_entered

Я возвращаю обещание от функции, которую я назначаю переменной области видимости, используемой в представлении, надеясь, что когда обещание будет разрешено готовым событием, будет доступен массив объектов поблизости.

obj.findGroupsInViscinity = function(pos){ 
    var gFire = factoryAuth.geoFire; 
    var fbaseRef = factoryAuth.usersRef; 
    var groupsInQuery = {}; 
    var groupsInQueryAr = []; 
    var deferred = $q.defer(); 

    var geoQuery = gFire.query({ 
     center: [pos.coords.latitude, pos.coords.longitude], 
     radius: 2 
    }) 

    geoQuery.on("key_entered", function(groupId, groupLocation, distance) { 
     console.log("--> key_entered 1"); 
     groupsInQuery[groupId] = true; 

     // Look up the vehicle's data in the Transit Open Data Set 
     fbaseRef.child("groups").child(groupId).once("value", function(dataSnapshot) { 

     console.log("--> key_entered 2"); 

     // Get the vehicle data from the Open Data Set 
     group = dataSnapshot.val(); 

     // If the vehicle has not already exited this query in the time it took to look up its data in the Open Data 
     // Set, add it to the map 
     if (group !== null && groupsInQuery[groupId] === true) { 
      console.log("Adding group", group); 

      // Add the group to the list of groups in the query 
      groupsInQuery[groupId] = group; 
      groupsInQueryAr.push({"name": group.name}); 
     } 
     }) 
    }) // end ke_entered monitoring 

    geoQuery.on("ready", function() { 
     console.log("GeoQuery ready event received. groupsInQueryAr = ", groupsInQueryAr); 

     deferred.resolve(groupsInQueryAr); 
     geoQuery.cancel(); 
     console.log("GeoQuery canceled"); 
    }) // Cacnel the geoQuery once we have gotten all the groups in viscinity 

return deferred.promise; // Return a promise that will be resolved when ready event fires 
} 

Включенный под консольным выходом вызов этой функции. enter image description here

Что я замечаю, что key_entered часть кода вызывается дважды подряд, но перед кодом для обработки key_entered событие завершает, готовое событие вызывается, потому что все key_entered события увольняют. Поэтому, когда ключевая часть логики строит массив, который я хочу передать в решении обещания, он не готов в то время, когда я разрешаю обещание в готовом событии.

Как я могу гарантировать, что я разрешу обещание после того, как все события, обработанные key_entered, обработаны, и мой массив объектов был построен правильно?

Thanks, Sanjay.

ответ

3

Я бы сказал, что это немного an XY problem, и я бы посоветовал вам просто загружать рестораны в ваше мнение по мере их получения. В большинстве случаев это, скорее всего, будет лучшим пользовательским интерфейсом.

Это, если вы хотите сделать то, о чем вы просите, вы можете заставить его работать, используя $.all(). По существу, создавайте и возвращайте свое отложенное обещание. Начните с пустого списка и для каждого события key_entered, вставьте новое обещание в список. Затем в своем обратном вызове ready сделайте $q.all() в списке обещаний и после их завершения (в then() обещания) сделайте deferred.resolve().

Смежные вопросы