2015-08-26 185 views
2

我有以下功能登录通过在某一给定时间的函数是句子中的人物,看看下面的功能:For循环不允许的setTimeout执行

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

以上程序员工作正常,现在如果我添加一个for循环到上面的程序IE 包裹的setTimeout在for循环中,

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

所有的人物在一次打印,为什么呢?

为什么for循环不符合setTimeout间隔?有人可以解释吗?

+3

你有一个函数,这是不允许的内部函数,函数typeit是内部功能print_string –

+0

岂不等于说他们调用关闭?任何文件来证明你的话是什么?我是一个JS新手,所以不是专家本人! –

+2

这真是毫无根据的@BhawinParkeria – charlietfl

回答

2

如果你想timer参数充当的实际间隔,使用此:

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

这里是一个fiddle

您的困惑是for循环立即发生,或者与处理器允许的速度一样快。当setTimeout处理程序执行时,它与您可能期望的范围有不同的范围。作用域不再位于for循环内(因为发生在处理器的不同勾号中),因此打印变量丢失。为了解决这个问题,我使用了所谓的闭包。我正在建立一个函数,打印我需要的特定变量,并将它作为参数传递给setTimeout

了解更多关于closures here

+0

这也具有相同的效果,一次打印出所有字符:(而不是间隔打印字符! –

+1

循环在瞬间完成...创建多个调用功能,它将同时触发 – charlietfl

+0

@Tenali_raman请参阅修订后的答案。有一个示例小提琴和一个解释。 – shennan

0

这两段代码的区别是:
第一次您在每次触发超时功能时设置定时器。
在第二种情况下,您在每个“foreach”迭代中同时(几乎)设置所有定时器,以便同时触发事件。
您可以通过timer + = 50来防止它。

0

我会尽力应归结为:

你传递一个字符串30个字符的功能print_string,使for循环将迭代和调用setTimeout 30倍。 50ms后,第一个setTimeout回调将被调用,并将输出字符串的第一个字符。变量strt_point将递增。然后第二个for循环迭代的第二个setTimeout回调将立即调用,并且由于strt_point已被增加,第二个字符将被打印。

问题是,对于for循环的所有迭代,您都有一个变量strt_point,以便所有字符在50ms后打印。

0

我想你想是这样的:

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>