AngularJS:promis返回相同的值

时间:2015-01-19 09:07:44

标签: angularjs firebase promise angular-services

我们有以下工厂从firebase检索数据:

    .factory('UserInfo', ["$firebase", "$q",
    function($firebase, $q) {
        //initialize firebase
        var ref = new Firebase("https://xxx.firebaseio.com/users/data");
        var dataRef = $firebase(ref).$asArray();

        //$q for synchronous method call
        var deferred = $q.defer();
        var promise = deferred.promise;

        return {
            getProfile: function(ID) {
                console.log(ID);
                dataRef.$loaded()
                    .then(function(data) {
                        var record = data.$getRecord(ID);
                        var profileData = {
                            "profileID": record.profileID,
                            "displayName": record.displayName,
                            "email": record.email,
                            "picture": record.picture,
                            "birthdate": record.birthdate,
                            "age": record.age,
                            "hobby": record.hobby,
                            "gender": record.gender,
                            "firstname": record.firstname,
                            "lastname": record.lastname,
                            "numberHuggs": record.numberHuggs,
                            "rating": record.rating
                        };
                        //console.log(profileData);
                        deferred.resolve(profileData);
                        //return profileData;

                    }) // end then

                .catch(function(error) {
                    console.error("Error getting UserInfo:", error);
                    deferred.reject("Error getting UserInfo: " + error)
                }); // end catch

                return deferred.promise;
            } // end function(ID)
        };
    } // end function
]) //end factory

在我们的控制器中,我们使用

访问此工厂
$scope.chatList.$loaded().then(function() {
    for (var i = 0; i < ($scope.chatList).length; i++) {
                                        console.log($scope.chatList[i].otherProfileID);

        UserInfo.getProfile($scope.chatList[i].otherProfileID).then(function(value) {
                            console.log(value);

        });
    };

});

本质上,它需要用户的profileID,将它们发送到UserInfo.getProfile(),然后getProfile返回一个包含我们数据的对象。 遗憾的是,这不起作用。我们的控制器代码中的console.log()表明,不同的profileID在工厂中处理,但最后,它返回(console.log(value))第一个userprofile 3次(我们在数组中有3个不同的profileID) ) 任何提示?

2 个答案:

答案 0 :(得分:3)

您应该为每次调用getProfile创建一个新的延迟对象。 您的代码会创建一次,因此对同一个对象始终会发生解析。

尝试移动此块:

//$q for synchronous method call
var deferred = $q.defer();
var promise = deferred.promise;

进入getProfile函数体

答案 1 :(得分:1)

dataRef.$loaded()已经返回了一个可用的,因此您不需要创建/解决您自己的延迟 - 而且,这实际上是不好的做法(也就是Deferred Anti-pattern )。

相反,返回dataRef.$loaded().then()链的结果,在当时的回调中获得适当的回报。

通过进一步整理,整个过程应简化如下:

.factory('UserInfo', ["$firebase", "$q", function($firebase, $q) {
    var ref = new Firebase("https://xxx.firebaseio.com/users/data"),
        dataRef = $firebase(ref).$asArray();
    return {
        getProfile: function(ID) {
            return dataRef.$loaded().then(function(data) {
                return angular.extend({}, data.$getRecord(ID));//much shorter than transcribing properties manually
            }).catch(function(error) {
                console.error("Error getting UserInfo: ", error.message);
                return $q.reject(error);
            });
        }
    };
}]);