奇怪的JavaScript范围错误

时间:2017-04-11 01:14:41

标签: javascript angularjs scope

所以在我的代码中,我有一个函数,用于比较当前时间和经过的时间(以毫秒为单位)并吐出一个人类可读的数字。因此,例如,如果您将1491869404676传入此函数,它会将该数字与JS new Date()。getTime()函数进行比较,并吐出20米。

现在,我有一段代码似乎自己调用了这个函数。我确信这是一个我不明白的范围问题。但是如果你查看第二个控制台日志,它会以毫秒为单位正确返回时间。一旦我将这个对象推入momentArray(这是一个全局的)它就会以某种方式调用我之前提到的函数并将其更改为人类可读的格式。为了方便起见,我评论了我所说的话。

function getMomentsWithinRadius(momentsInStates) {
    var deferred = $q.defer();
    for(var i = 0; i < momentsInStates.length; i++) {
        (function(i) {
            awsServices.getMomentMetaData(momentsInStates[i].Key).then(function(metaData) {
                console.log("GET MOMENTS META DATA")
                console.log(metaData.time); //Returns 1491869404676
                momentArray.push({ 
                    key: constants.IMAGE_URL + momentsInStates[i].Key, 
                    description: metaData.description,
                    likes: metaData.likes,
                    location: metaData.location,
                    time: 1491869404676, //<-- Simplified to make a point, should be metaData.time
                    uuids: metaData.uuids,
                    views: metaData.views
                });
                console.log(momentArray); //Time field should be 1491869404676 but I get 20m
                if(momentArray.length === momentsInStates.length) {
                    var temp = momentArray; //<-- My attempt to mess with the scope
                    deferred.resolve(temp);
                }
            }, function(error) {
                console.log("ERROR - momentService.getMomentsWithinRadius");
                console.log(error);
            });
        })(i);
    }
    if(momentsInStates.length === 0) {
        deferred.resolve(momentsInStates);
    }
    return deferred.promise;
};

此函数将返回此初始化函数(省略一些代码):

        getMomentsWithinRadius(momentsInStates).then(function(moments) {
            console.log("GET MOMENTS WITHIN RADIUS");
            console.log(moments);
            momentArray = moments;
            $ionicLoading.hide().then(function() {
                deferred.resolve(moments);      
            });
return deferred.promise;
}

这些功能都存在于服务中。当此函数返回到控制器时,控制器应该使用我之前提到的函数来转换该奇怪的数字,以便很好地显示在视图上。

function updateView() {
        momentsService.initializeView()
        .then(function(moments){
            console.log("INITIALIZE VIEW");
            console.log(moments);
            if(moments.length > 0) {
                vm.imageArray = updateObject(moments);
                vm.imageArray[0].time = core.timeElapsed(vm.imageArray[0].time); //<-- If I remove this line everything works perfectly.
            }
            else {
                vm.imageArray = undefined;
            }
        }, function(error) {
            vm.currentImage = undefined;
        });
    };

有趣的是,如果我删除有关core.timeElasped()的内容,一切都按预期工作。 momentArray log alllll在getMomentsWithinRadius服务中的方式显示了一个长数字,并且不会自动转换它。当然,如果我把这条线拿出来,那么现在看来这个疯狂的长数字是没有人理解的。

我不知道为什么我的控制器代码似乎正在影响服务上的某个全局变量。

感谢任何帮助。 谢谢!

编辑:

根据你的建议我试过

function getMomentsWithinRadius(momentsInStates) {
    var deferred = $q.defer();
    var temp = [];
    for(var i = 0; i < momentsInStates.length; i++) {
        (function(i) {
            awsServices.getMomentMetaData(momentsInStates[i].Key).then(function(metaData) {
                console.log("GET MOMENTS META DATA")
                console.log(metaData);
                temp.push({ 
                    key: constants.IMAGE_URL + momentsInStates[i].Key, 
                    description: metaData.description,
                    likes: metaData.likes,
                    location: metaData.location,
                    time: metaData.time,
                    uuids: metaData.uuids,
                    views: metaData.views
                });
            console.log(temp);
            if(temp.length === momentsInStates.length) {
                momentArray = temp;
                deferred.resolve(temp);
            }
        }, function(error) {
            console.log("ERROR - momentService.getMomentsWithinRadius");
            console.log(error);
        });
        })(i);
    }
    if(momentsInStates.length === 0) {
        deferred.resolve(momentsInStates);
    }
    return deferred.promise;
};

它仍然显示同样的问题。我创建了一个新的临时对象,并为其分配了我想要的属性。我做错了吗?

1 个答案:

答案 0 :(得分:0)

避免使用延迟反模式,并使用Promise.all的Promises的真正功能。第一个块中的代码只是

function getMomentsWithinRadius(momentsInStates) {
    return Promise.all(momentsInStates.map(moment =>
        awsServices.getMomentMetaData(moment.Key).then(metaData => ({
            key: constants.IMAGE_URL + moment.Key, 
            description: metaData.description,
            likes: metaData.likes,
            location: metaData.location,
            time: metaData.time,
            uuids: metaData.uuids,
            views: metaData.views
        }))
    ));
}
相关问题