这是一个很难解释的问题,但它可能来自对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是迭代次数。
为了尝试理解这个问题,我已经将它显示在控制台中,在我看来函数getPoint
只是在while循环结束后使用日期对象调用它的状态。任何人都可以解释为什么会出现这种情况,如果有可能的话呢?
编辑我尝试用以下代码替换我的代码,但我仍然只能获得:
[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);
});
}
更新:这是因为在调用回调之前日期对象已经改变了。因此,我的问题是如何确保callBack在原始AJAX调用时使用其状态中的对象被称为?
答案 0 :(得分:0)
您需要创建新的日期对象,因为当调用.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]];
});
}());
它不会改变最终结果,但我在done处理程序中注释了newPoint和$ .extend调用的创建,并用一个简单的点赋值替换它们,因为我认为这样更有效。
请记住,如果您只是在while循环后尝试console.log(points),那么很可能没有您期望的所有点 - 因为并非所有的ajax调用都已完成。你可能需要做这样的事情来给ajax调用足够的时间来返回:
console.log('displaying points in 10 seconds:');
setTimeout(function () {
console.log(points);
}, 10000);