Js中for循环的阻塞机制详解编程语言
Js阻塞机制,跟Js引擎的单线程处理方式有关,每个window一个JS线程。所谓单线程,在某个特定的时刻只有特定的代码能够被执行,并阻塞其它的代码。
由于浏览器是事件驱动的(Event driven),因此浏览器中很多行为是异步(Asynchronized)的,很容易有事件被同时或者连续触发。当异步事件发生时,会创建事件并放入执 行队列中,等待当前代码执行完成之后再执行这些代码,如鼠标点击事件发生、定时器触发事件发生、XMLHttpRequest完成回调这些事件,都会被放 入执行队列中等待。
关于Js的阻塞机制,可以看下面一段代码,一般,我们会认为,这段代码会log出来0,1,2
for(var i=0;i i++){ setTimeout(function(){ console.log(i); }, (i+1)*1000);
}
而实际上,这段代码log出来的结果是 3,3,3。这是js新手很容易遇到的问题,具体原因就是因为for循环的阻塞机制。在上面的代码中,setTimeout这个定时器需要等待for循环 执行完成,而for循环执行完成了之后,i已经为3了,此时才开始执行setTimeout,因此console.log(i)会是3。
至于为什么i会是3,请回顾一下for循环的执行顺序,当i为2的时候,满足循环条件,执行代码块,然后i++,此时i为3,不满足循环条件,不执行代码块,循环停止。
对于for循环,记住,是在不满足条件的情况下停止循环,对于以上代码,可以看出,i=3的时候才不满足。
怎么解决事件阻塞其实,阻塞作为js引擎的处理方式,我们最好不要想着解决“阻塞”,而是让我们想执行的代码,插入到“主线程”中。这么说比较不易理解,还是以上面的代码为例,直接上代码好了
for(var i=0;i i++){ (function(i){ setTimeout(function(){ console.log(i); }, (i+1)*1000); })(i) }
再上面的代码中,我们加了一个立即执行的匿名函数,并且将for循环的i作为实参传入进去。这样,setTimeout就会被立即执行,而不会等待(这里不太了解细节,就不多说了,大概猜测为新开了一个临时的线程,立即执行匿名函数,然后再立即切换回来)。
本文主要在说明如何解决这一类问题,对于底层原理,还待继续挖掘。
注意:html5支持Web worker功能,可以写多线程。
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/17016.html
cjavaxml相关文章
- html js 全局 变量,JS定义全局变量
- 『Three.js』几个简单的入门动画(新手篇)
- [html]js无缝循环滚动图片示例代码
- Js:indexOf() 和 lastIndexOf() 的区别[通俗易懂]
- html如何只刷新页面指定,js控制页面刷新 JS刷新当前页面的几种方法总结
- JS中的那些循环
- 优化谷歌联盟广告JS加载缓慢问题,提高网站页面的加载速度
- js 数组去除重复数据-当WPS开始像支持VBA一样支持JS语言时,微软又该何去何从?
- JS循环练习-简易银行ATM
- js中的cookie操作详解编程语言
- jQuery图片切换插件jquery.cycle.js详解编程语言
- JS获取Session中保存的值详解编程语言
- JS window对象的使用(非常详细)
- JS技术连接Oracle数据库实现数据交互(js连接oracle实例)
- Oracle中使用JS变量管理数据(oracle使用js变量)
- Oracle中JS的优势让数据库性能提升(oracle中 js)
- Redis中的订阅机制及其在JS中的应用(redis 订阅 js)
- 写了个XML+Tree无穷树js版
- js实现的跟随鼠标移动的时钟效果(中英文日期显示)
- 友情链接横向文字上下间隙循环滚动JS效果
- js获取坐标通过JS得到当前焦点(鼠标)的坐标属性
- 兼容IE和Firefox火狐的上下、左右循环无间断滚动JS代码
- 一个简单的JS时间控件示例代码(JS时分秒时间控件)
- node.js中的fs.rmdirSync方法使用说明
- js和jquery中循环的退出和继续学习记录
- 小结Node.js中非阻塞IO和事件循环