3
回答
for循环里面设置setTimeout弹出数据顺序是乱的
利用AWS快速构建适用于生产的无服务器应用程序,免费试用12个月>>>   
 代码1:for(var i=0;i<10;i++){
        (function(index){
            setTimeout(function (){
                alert(index);
            },1000);
        })(i);

 }

代码2:

for(var i=0;i<10;i++){
        (function(index){
            setTimeout(a(index),1000);
        })(i);
    }


    function a(param){
        alert(param);
    }

为什么代码1不能控制顺序,弹出来的数字顺序是乱的 。代码2的可以

<无标签>
举报
回忆若风
发帖于3年前 3回/1K+阅
共有3个答案 最后回答: 3年前

在2里面,你的写法根本没用到settimeout定时器,所以相当于在循环体里面直接call a(),并且因为alert的阻塞作用,也就阻塞了循环,所以就是一步一步的执行循环了。

在1里面,确实启动了10个定时器,这个10个定时器在1秒后左右被唤醒,猜测这个地方有cpu竞争存在或者其它的浏览器内部优化逻辑,不保证严格的时间一致性。 

代码2使用了闭包与setTimeout,一般来说,使用闭包就可以解决这个问题

因为你使用setTimeout,也就是延时操作,js引擎空闲下来才会执行的代码

直到for循环会执行完毕之后js引擎空闲了,发现还有很多延时任务等着执行,此时的i已经不是预想的i了,而且都是最后相同的!

这时候会按照进入延时进入的顺序队列执行,而闭包保证了i参数的唯一与正确性。

原理上面的基本已经说了,如果你想既控制顺序又能设置延时的话,可以这样写:

 function a(param) {

    if(param < 9){

        alert(param);

        setTimeout(a(param+1), 1000)

}

}

a(0);

--- 共有 1 条评论 ---
rxso2v1llm对的,是这么写的 主要解决的问题就是:在阻塞的时候,不允许函数回调堆积, 这样写就可以解决了~所以我几乎不写setinterval,而用这种写法 2年前 回复
顶部