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 ?

Answers:

Answer

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.

Answer

The difference of the two pieces of code is:
In the first one you set the timer each time the timeout function is triggered.
In the second case you set all the timers simultaneously (almost) in each "foreach" iteration, so the events fire the same time.
You can prevent it by timer+=50.

Answer

I'll try to exlain:

You are passing a string with 30 characters to the function print_string so that the for loop will iterate and call setTimeout 30 times. After 50ms the first setTimeout callback will be called and will output the first char of your string. The variable strt_point will be incremented. Then the second setTimeout callback of your second for loop iteration will be called immediately and because strt_point is has already been incremented, the second char will be printed.

The problem is that you have ONE variable strt_point for all iterations of the for loop so that all chars are printed after 50ms.

Answer

I think you want something like this:

var print_string = function ( param, interval ) {
  var
    i = 0,
    len = param.length,
    
    result = document.getElementById( 'result' ),
    
    // function called for every characters
    next = function () {
      // get the current character
      var char = param.charAt(i);
      
      // do what you want with them
      result.innerHTML += char;
      
      // if not the end of the string
      if ( ++i < len ) {
        // continue after the interval
        setTimeout( next, interval );
      }
    }

  next();
}

print_string( 'hey there , whats up , hows the weather in Manhatten!', 50 );
<div id="result"></div>

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.