文章

关于setTimeout同步和异步问题

<script type="text/javascript">
function test(){
for(var i = 0; i < 5; i++){
setTimeout(function(){
alert(i)}, 100);
}
}
test();
</script>

第一段代码中,开发人员的本意应该是每隔100毫秒将i的值加1输出,然而这段代码并不能达到上述目的,因为i的值在循环中增加,这是一个同步时序,它在计时器事件被调用钱就已经发生了,最终计时器得到的结果是循环后的i值,也就是5次alert显示的结果都是5.

<script type="text/javascript">
function test(){
for(var i = 0; i < 5; i++){
setTimeout("alert("+i+")", 100);
}
}
test();
</script>

第二段代码中,开发人员意识到了这个问题,采用了拼接字符串的方式来调用计时器,由于i在字符串运算中被替换成了当前循环时的实际常量值,所以得到了正确的结果。

<script type="text/javascript">
function test(){
for(var i = 0; i < 5; i++){
(function(i){
setTimeout(function(){
alert(i)},100);
})(i);
}
}
test();
</script>

实际上,比字符串更好的模式是通过闭包,所以第三段代码中,开发人员通过闭包嵌套和不同时序的执行,巧妙地得到了正确的结果,并且比第二段代码更具效率和通用性。

2 0

发表评论