一个while循环中的Javascript函数

时间:2014-03-23 17:02:30

标签: javascript loops object 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是迭代次数。

为了尝试理解这个问题,我已经将它显示在控制台中,在我看来函数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调用时使用其状态中的对象被称为?

1 个答案:

答案 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);