【问题标题】:Javascript function in a while loopwhile循环中的Javascript函数
【发布时间】:2014-04-30 21:38:40
【问题描述】:

这是一个很难解释的问题,但它可能来自对 j​​avascript 如何处理对象的误解:

我试图在几年内建立一个点列表:我有两个日期对象,每个周期的年份都会递增。

我正在调用一个函数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 调用时使用处于其状态的对象叫什么?

【问题讨论】:

  • 一开始你是如何创建 td2 和 date2 对象的?
  • 没有人能解释为什么的情况,因为事实是肯定不是的情况。 getPoint is 在每次循环期间调用,使用该循环期间存在的值。如果您发布更多关于您为什么不这么认为的信息,我们可以尝试澄清您的困惑。
  • @ruakh,我会发布 console.log 结果,让我相信是这种情况
  • @Markasoftware:不,jsfiddle比直接在问题中提供信息更好。场外信息很好,只要它只是补充。
  • 啊我明白了,你的意思是因为调用是异步的,并且日期对象正在改变,当实际执行 ajax 时,日期已经改变了?

标签: javascript loops object while-loop


【解决方案1】:

您将需要创建新的日期对象,因为当调用 .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);

【讨论】:

    猜你喜欢
    • 2021-12-03
    • 2021-01-14
    • 1970-01-01
    • 2013-11-29
    • 2018-09-25
    • 2021-11-04
    • 2017-06-07
    • 2021-03-08
    • 2016-07-23
    相关资源
    最近更新 更多