5

我遇到了一个问题,我的应用程序存在于 iframe 中,并且它是从外部域调用的。当 iframe 正确加载时,IE9 不会触发 load 事件,所以我认为我无法使用 setTimeout 来轮询页面。

无论如何,我想看看我的 setTimeout 完成通常需要多长时间,所以我希望能够记录 setTimeout 从我的回调中触发的延迟,但我不确定如何将该上下文传递给它,所以我可以记录它。

App.readyIE9 = function() {
  var timings = [1,250,500,750,1000,1500,2000,3000];    
  for(var i = 0; i < timings.length; i++) {
    var func = function() {
    if(App.ready_loaded) return;
      console.log(timings[i]);
      App.readyCallBack();
    };
    setTimeout(func,timings[i]);
  }
};

我不断收到 LOG: undefined 在 IE9 的控制台中。

完成此任务的正确方法是什么?

谢谢

4

3 回答 3

11

当您的函数setTimeout在未来某个时间被调用时,循环的值i已经增加到它的范围的末尾,所以报告。forconsole.log(timings[i]);undefined

i在该函数中使用,您需要在函数闭包中捕获它。有几种方法可以做到这一点。我建议使用自执行函数来捕获这样的值i

App.readyIE9 = function() {
  var timings = [1,250,500,750,1000,1500,2000,3000];    
  for(var i = 0; i < timings.length; i++) {
    (function(index) {
        setTimeout(function() {
            if(App.ready_loaded) return;
            console.log(timings[index]);
            App.readyCallBack();
        }, timings[index]);
    })(i);
  }
};

作为对谁起作用的一点解释:i作为该函数的第一个参数传递给自执行函数。第一个参数被命名index并在每次调用自执行函数时被冻结,因此for循环不会在setTimeout执行回调之前导致它发生变化。因此,index在自执行函数内部引用将获得每个setTimeout回调的正确数组索引值。

于 2012-06-01T18:25:58.450 回答
11

发生这种情况是因为您没有关闭i. func循环完成后,i是 8 ( timings.length),它不存在于数组中。

你需要做这样的事情:

App.readyIE9 = function() {
  var timings = [1,250,500,750,1000,1500,2000,3000];    
  for(var i = 0; i < timings.length; i++) {
    var func = function(x) {
      return function(){
          if(App.ready_loaded) return;
          console.log(timings[x]);
          App.readyCallBack();
      };
    };
    setTimeout(func(i),timings[i]);
  }
};
于 2012-06-01T18:25:59.453 回答
3

当您使用setTimeoutsetInterval回调时,这是一个常见的问题。您应该将i值传递给函数:

var timings = [1, 250, 500, 750, 1000, 1500, 2000, 3000],
    func = function(i) {
        return function() {
            console.log(timings[i]);
        };
    };

for (var i = 0, len = timings.length; i < len; i++) {
    setTimeout(func(i), timings[i]);
}

演示:http: //jsfiddle.net/r56wu8es/

于 2012-06-01T18:26:00.537 回答