阅读前提理解:
1.setTimeout()的回调函数是在代码段里的代码全部执行完才执行的(相当于setTimeout()被放到程序块最后才执行);
2.注意setTimeout()回调函数中的this(文中的例子开始的代码this是在for里面);
3.设置timer(对setTimeout()的调用)几乎不消耗时间,如果有连续的延时请求的话,而且每一个时间延迟值是相同的,那么一旦经过足够的时间,所有延时处理程序将一个接一个快速连续调用。
setTimeout()是js中的一类重要函数,将一段代码延迟一定时间并异步执行。但是这个函数经常不听话。在实践中,可能经常有人碰到类似下面的这种情况:
for (var i = 1; i <= 2; i++) { setTimeout(function() { alert(i) }, 100); }
我们期望的结果是,先隔100毫秒弹出1,再隔100毫秒弹出2。但是跑起来后,alert的两次内容都是数字3,而且紧挨着输出,并不是自己所期望的先1后2。有一种很基础的面试题是,如何合理改动代码,使它返回期望的结果?
其实很简单。在stackoverflow上早有大神解释了,可以参考这个链接
答案翻译成中文如下(并做了部分修改方便理解):
---------------------------------------------------------------------------------
你要为每个定时器处理函数创建不同的“i”变量副本。比如这样:
function doSetTimeout(i) { setTimeout(function() { alert(i); }, 100); } for (var i = 1; i <= 2; ++i) doSetTimeout(i);
function doScaledTimeout(i) { setTimeout(function() { alert(i); }, i * 5000); }
(100毫秒超时,效果不会很明显,所以我设置的数字高达5000)
“i”值乘以基础延迟值,所以循环5次将导致分别延迟5秒,10秒,15秒,20秒,和25秒。