Passing parameters into a closure for setTimeout

前端 未结 3 1485
野趣味
野趣味 2021-01-19 02:18

I\'ve run into an issue where my app lives in an iframe and it\'s being called from an external domain. IE9 won\'t fire the load event when the iframe loads properly so I t

3条回答
  •  南笙
    南笙 (楼主)
    2021-01-19 02:25

    When your function gets called by setTimeout sometime in the future, the value of i has already been incremented to the end of it's range by the for loop so console.log(timings[i]); reports undefined.

    To use i in that function, you need to capture it in a function closure. There are several ways to do that. I would suggest using a self-executing function to capture the value of i like this:

    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);
      }
    };
    

    As a bit of explanation for who this works: i is passed to the self-executing function as the first argument to that function. That first argument is named index and gets frozen with each invocation of the self-executing function so the for loop won't cause it to change before the setTimeout callback is executed. So, referencing index inside of the self-executing function will get the correct value of the array index for each setTimeout callback.

提交回复
热议问题