js中for循环的阻塞机制
2020-05-04 本文已影响0人
段煜华
关于js的阻塞机制,可以看下面一段代码,一般我们会认为,这段代码会log出来0,1,2
for(var i = 0; i < 3; i++) {
setTimeout(function() {
console.log(i);
}, i * 1000);
}
而实际上,这段代码log出来的结果是 3,3,3
;具体原因是因为for循环的阻塞机制。在上面的代码中,setTimeout这个定时器需要等待for循环 执行完成,而for循环执行完成了之后,i已经为3了,此时才开始执行setTimeout,因此console.log(i)会是3。
由于浏览器是事件驱动的(Event driven),因此浏览器中很多行为是异步(Asynchronized)的,很容易有事件被同时或者连续触发。当异步事件发生时,会创建事件并放入执 行队列中,等待当前代码执行完成之后再执行这些代码,如鼠标点击事件发生、定时器触发事件发生、XMLHttpRequest完成回调这些事件,都会被放 入执行队列中等待。
其实,阻塞作为js引擎的处理方式,我们最好不要想着解决“阻塞”,而是让我们想执行的代码,插入到“主线程”中。代码如下:
for(var i = 0; i < 3; i++) {
(function(i) {
setTimeout(function() {
console.log(i);
}, i * 1000);
})(i)
}
再上面的代码中,我们加了一个立即执行的匿名函数,并且将for循环的i作为实参传入进去。这样,setTimeout就会被立即执行,而不会等待