[英]Javascript function in a while loop
这是一个很难解释的问题,但可能是由于对javascript如何与对象一起使用的误解造成的:
我正在尝试建立几年内的点列表:我有两个日期对象,每个周期中的年份递增。
我正在调用使用日期对象构建点的函数getPoint
,这是代码:
while(td2.getTime()<date2.getTime())
{
td1.setYear(td1.getFullYear()+1);
td2.setYear(td2.getFullYear()+1);
console.log(td1);
test=getPoint(sessionStorage.Link,stat,td1.getFullYear()+'-'+td1.getMonth()+1+'- '+td1.getDate(),td2.getFullYear()+'-'+td2.getMonth()+1+'-'+td2.getDate());
$.extend(points,test);
}
getPoint函数是这样的:
function getPoint(who,stat,date1,date2){
string=date1+"/"+date2;
var point={};
$.ajax({
type:'GET',
url: who +'/'+ stat + '/'+date1+'&'+date2,
data:{"token" : member.token},
dataType:'JSON',
error: function(){
point={};
},
success:function(data){
stat=stat.split('/');
stat=stat[1];
point[string]=data[stat];
}
});
return point;
}
在while循环结束时,我期望点重新组装:
points={date1/date2: value, date1+(1year)/date2+(1year) : value, ..., date1+(n years)/date2+(n years) : value}
不幸的是,我只得到:
points = {date1/date2 : value, date1+nyears/date2+nyears : value}
其中n是迭代次数。
为了尝试理解问题,我将其显示在控制台中,在我看来,仅在while循环完成后,使用日期对象以其状态调用getPoint
函数。 如果有可能的话,谁能解释为什么会这样?
编辑我试图用以下代码替换我的代码,但仍然只能得到:
[Log] Object (mystats.js, line 61)
2015-2016: 0
__proto__: Object
在日志中。
function getPoint(who,stat,date1,date2){
return $.ajax({
type:'GET',
url: who +'/'+ stat + '/'+date1+'&'+date2,
data:{"token" : member.token},
dataType:'JSON',
});
}
var td1=new Date(date1.getTime());
var td2=new Date(date1.getTime());
var points={};
td2.setFullYear(td2.getFullYear()+1);
getPoint(sessionStorage.Link,stat,td1.getFullYear()+'-'+(td1.getMonth()+1)+'-'+td1.getDate(),td2.getFullYear()+'-'+(td2.getMonth()+1)+'-'+td2.getDate()).done(function(result)
{
tStat=stat.split('/');
points[td1.getFullYear()+'-'+td2.getFullYear()]=result[tStat[1]];
});
while(td2.getTime()<date2.getTime())
{
td1.setYear(td1.getFullYear()+1);
td2.setYear(td2.getFullYear()+1);
getPoint(sessionStorage.Link,stat,td1.getFullYear()+'-'+(td1.getMonth()+1)+'-'+td1.getDate(),td2.getFullYear()+'-'+(td2.getMonth()+1)+'-'+td2.getDate()).done(function(result){
tStat=stat.split('/');
var newPoint={};
newPoint[td1.getFullYear()+'-'+td2.getFullYear()]=result[tStat[1]];
$.extend(points,newPoint);
});
}
更新 :这是因为日期对象在调用回调之前已更改..因此,我的问题是,如何确保在调用原始AJAX调用时,callBack在其状态下使用该对象?
您将需要创建新的日期对象,因为在调用.done回调时,td1和td2将不会具有与分派ajax调用时相同的值。 我认为您必须创建一个闭包,在其中创建两个新的日期变量:
(function () {
var innerTd1 = new Date(td1.getTime());
var innerTd2 = new Date(td2.getTime());
getPoint(sessionStorage.Link, stat, innerTd1.getFullYear()+'-'+(innerTd1.getMonth()+1)+'-'+innerTd1.getDate(),innerTd2.getFullYear()+'-'+(innerTd2.getMonth()+1)+'-'+innerTd2.getDate()).done(function (result) {
tStat=stat.split('/');
//var newPoint={};
//newPoint[td1.getFullYear()+'-'+td2.getFullYear()]=result[tStat[1]];
//$.extend(points,newPoint);
points[innerTd1.getFullYear()+'-'+innerTd2.getFullYear()] = result[tStat[1]];
});
}());
它不会改变最终结果,但是我已经在完成的处理程序中注释掉了newPoint和$ .extend调用的创建,并用一个简单的点分配代替了它们,因为我认为这样做效率更高。
记住,如果您只是在while循环之后尝试console.log(points),则很可能没有您期望的所有点-因为并非所有的ajax调用都将完成。 您可能需要执行以下操作以使ajax调用有足够的时间返回:
console.log('displaying points in 10 seconds:');
setTimeout(function () {
console.log(points);
}, 10000);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.