AngularJS: promis returns 相同的值

AngularJS: promis returns same value

我们有以下工厂从 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);

        });
    };

});

本质上,它获取用户的配置文件 ID,将它们发送到 UserInfo.getProfile() 和 getProfile,然后 returns 一个包含我们数据的对象。 遗憾的是,这不起作用。我们的控制器代码中的 console.log() 表明,不同的 profileID 在工厂中处理,但最终,它 returns (console.log(value)) 第一个用户配置文件 3 次(我们在数组中有 3 个不同的 profileIDs) 有什么提示吗?

您应该为每次调用 getProfile 创建一个新的延迟对象。 您的代码创建它一次,因此解析总是发生在同一个对象上。

尝试移动这个方块:

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

进入getProfile函数体

dataRef.$loaded() 已经 return 是一个 thenable,因此你不需要 create/resolve 你自己的延迟 - 此外,这样做实际上是不好的做法(又名 Deferred Anti-pattern).

相反,return 您的 dataRef.$loaded().then() 链的结果,在当时的回调中做出了合适的 returns。

随着进一步整理,整个事情应该简化如下:

.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);
            });
        }
    };
}]);