1

我是 GeoFire、FireBase 和 Angular 的新手。我正在尝试创建一个函数,该函数将获取一些坐标并返回这些坐标附近的一些对象。

我从分配给视图中使用的范围变量的函数返回一个承诺,希望当准备好的事件解决承诺时,附近的对象数组将可用。

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
}  

包含在调用此函数的控制台输出下方。 在此处输入图像描述

我注意到代码的 key_entered 部分连续调用了两次,但在处理 key_entered 事件的代码完成之前,调用了 ready 事件,因为所有 key_entered 事件都已触发。因此,虽然逻辑的 key_entered 部分正在构建我想要传递的数组来解决承诺,但在我解决 ready 事件中的承诺时它还没有准备好。

在处理完所有 key_entered 事件并且正确构建对象数组后,如何确保我解决了承诺?

谢谢,桑杰。

4

1 回答 1

3

我会说这是一个 XY 问题,我建议您在获得餐厅时将它们加载到您的视图中。在大多数情况下,这可能是更好的用户体验。

话虽如此,如果您想做您所要求的事情,您可以使用$.all()使其工作。本质上,创建并返回您的延期承诺。从一个空列表开始,对于每个key_entered事件,将一个新的承诺推送到列表中。然后,在您的ready事件回调中,$q.all()在 promise 列表中执行 a ,一旦它们完成(在then()promise 中),执行deferred.resolve().

于 2015-12-09T20:26:26.233 回答