Angularjs 使用geofire和firebase在阵列中循环时重复数据

Angularjs 使用geofire和firebase在阵列中循环时重复数据,angularjs,loops,firebase,q,geofire,Angularjs,Loops,Firebase,Q,Geofire,请看一下我的代码 var posts = PostsData.getPosts(); var postFunc = function(key) { return posts[key]; } $scope.$watch($scope.active, function() { $timeout(function() { var markers = []; for (var key in posts) { co

请看一下我的代码

  var posts = PostsData.getPosts();   
  var postFunc = function(key) {
      return posts[key];  
  }

  $scope.$watch($scope.active, function() {
      $timeout(function() {
    var markers = [];

    for (var key in posts) {

          console.log(key);
          var p = gf.get(key).then(function(location) { 
          var post = postFunc(key);
          console.log(key);
          return ({
            idKey: key,
            title: post.title,
            coords: {
              latitude: location[0],
              longitude: location[1]
            }
           });
      });
      markers.push(p);

    }

    $q.all(markers).then(function(markers) {
    $scope.markers = markers;
    });

  });
})
}

在循环中有两行“console.log(key)”。 第一个console.log打印数据的精确表示,该数据是唯一的密钥。第二个console.log打印重复的相同数据,这是不准确的。我很难理解为什么会这样


非常感谢您的帮助。

从第二个
console.log(key)
开始,您具有相同的值是很正常的。原因是您的异步函数
gf.get(key).then(function(location){..}
。调用此函数时,您的循环已完成执行,并且
键的值是循环中的最后一个值。我不确定是什么
gf。get
做什么,但如果
posts
是一个数组,则可以借助递归实现结果,如下所示

var posts = PostsData.getPosts();   
var postFunc = function(key) {
    return posts[key];  
}

var markers = [];
var getMarkers(key) {

    if (key > posts.length - 1) {

        // promise resolved for each item in posts
        $q.all(markers).then(function(markers) {
            $scope.markers = markers;
        }

        return;
    }

    console.log(key);
    gf.get(key).then(function(location) {
        var post = postFunc(key);
        console.log(key);
        markers.push({
            idKey: key,
            title: post.title,
            coords: {
                latitude: location[0],
                longitude: location[1]
            }
        });

        getMarkers(++key);
    });
}

$scope.$watch($scope.active, function() {
    markers = [];
    getMarkers(0);
});

注意:在这种方法中,我们等待每个承诺得到解决,然后再进行下一次调用
gf。获取

另一种解决问题的方法是使用IIFE闭包

var markers = [];

for (var key in posts) {
    //IIFE closure
    (function (key) {
        console.log(key);
        var p = gf.get(key).then(function(location) { 
            var post = postFunc(key);
            console.log(key);
            return ({
                idKey: key,
                title: post.title,
                coords: {
                    latitude: location[0],
                    longitude: location[1]
                }
            });
        });
        markers.push(p);
    })(key);
}

通过使用iLife(),每个
键的值将被保留,直到
中的函数完成。然后
方法完成。

非常感谢!我不得不做一些轻微的更改,但它成功了。