setTimeout定时器的异步及let循环中的同步异步问题 个人理解笔记

新手个人理解  如有误解   敬请各位前辈评论指出 谢谢

例1: for循环setTimeout定时器:

for(var i = 1 ; i <= 5; i++){
(function(){
    setTimeout(function timer(){
        console.log(i);
        }
,1000*i);
    })();

}

上述代码预期分别输出 1  2  3  4  5   但是实际输出 6  6  6  6  6

原因:由于for循环与setTimeout函数是同步执行函数,而console.out是异步执行函数。异步执行函数需等待同步执行函数执行完毕才开始执行。所以当for循环与定时器全部加载执行完毕放进执行栈之后(即i=6时)console.log开始初始化。所以就出现了五次定时器循环的输出6.

例2: 函数实参传递:

for(var i = 1 ; i <= 5; i++){
(function(j){
    setTimeout(function timer(){
        console.log(j);
        }
,1000*j);
    })(i);

}

而这种写法就可以正确的输出预期结果。因为函数内不是直接传递for循环的值,将for循环与函数分离开来,通过参数的传递连接。这样console.log就不用等待for循环全部执行完毕。

例3: let循环的setTimeout定时器:

for(let i = 1 ; i <= 5; i++){
    (function(){
        setTimeout(function timer(){
        console.log(i);
        }
,1000*i);

    })();

}

let定义的循环体也是可以正常输出预期。因为let的作用域实在代码块中,声明只能在自身的块里声明,不是像var那样作用于函数,所以就等于每一次循环都重新定义一次let i,这样循环就只能一次次给函数传值。在这里let本质上就是形成了一个闭包,就像例4。

例4:

var loop = function(_i){
setTimeout(function timer(){
console.log(_i);
},1000*_i);

}

for(var i = 1 ; i <= 5; i++){
loop(i);

}

闭包概念:当内部函数以某一种方式被任何一个外部函数作用域访问时,一个闭包就产生了!




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章