Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
338 views
in Technique[技术] by (71.8m points)

javascript - For loop does not allow setTimeout to execute

I have the below function that logs a character in a sentence passed to a function at a certain given time, have a look at the function below:

function print_string(param , timer) {

  var strt_point = 0,
      str_len = param.length,
      self = this;


  //typewritter();

  typeit();

  function typeit() {

    setTimeout(function(){

      console.log(param.substring(strt_point).charAt(0)); 

      if(strt_point < str_len ) {
        strt_point++; 
        typeit()
      }
    } , timer);
  } 

}

var str = print_string("hey there , whats up , hows the weather in Manhatten" , 50);
console.log(str);

The above programmer works fine, now if i add a for loop to the above programme I.E. WRAP THE setTimeout in a for loop ,

function print_string(param , timer) {

  var strt_point = 0,
      str_len = param.length,
      self = this;

  for(var i = 0 ; i < str_len ; i++) {

  //typewritter();

  typeit();

  function typeit() {

    setTimeout(function(){

      console.log(param.substring(strt_point).charAt(0)); 

      if(strt_point < str_len ) {
        strt_point++; 
        typeit()
      }
    } , timer);
  } 

}

var str = print_string("hey there , whats up , hows the weather in Manhatten" , 50);
console.log(str);

All the characters are printed at once , Why ?

Why is it that the for loop does not honor the setTimeout interval ? can anybody explain ?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

If you want the timer argument to act as an actual interval, use this:

function print_string(param, timer) {

  for(var i = 0 ; i < param.length ; i++) {

    setTimeout((function(char){

      return function () {

        console.log(char);

      }

    })(param.charAt(i)), timer * i);  
  }
}

var str = print_string("hey there , whats up , hows the weather in Manhatten" , 500);

Here is a fiddle.

The confusion for you is that a for loop happens immediately, or as fast as the processor will allow it. When the setTimeout handler executes, it has a different scope to what you're probably expecting. The scope is no longer within the for loop (because that happened in a different tick of the processor) so the print variable is lost. In order to get around this, I'm using what is called a closure. I'm building a function on the fly, to print the specific variable that I need, and passing it as an argument to setTimeout.

Read more about closures here.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...