Js阻塞机制,跟Js引擎的单线程处理方式有关,每个window一个JS线程。所谓单线程,在某个特定的时刻只有特定的代码能够被执行,并阻塞其它的代码。

由于浏览器是事件驱动的(Event driven),因此浏览器中很多行为是异步(Asynchronized)的,很容易有事件被同时或者连续触发。当异步事件发生时,会创建事件并放入执 行队列中,等待当前代码执行完成之后再执行这些代码,如鼠标点击事件发生、定时器触发事件发生、XMLHttpRequest完成回调这些事件,都会被放 入执行队列中等待。

关于Js的阻塞机制,可以看下面一段代码,一般,我们会认为,这段代码会log出来0,1,2

for(var i=0;i<3;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<3;i++){
(function(i){
setTimeout(function(){
console.log(i);
}, (i+1)*1000);
})(i)
}

再上面的代码中,我们加了一个立即执行的匿名函数,并且将for循环的i作为实参传入进去。这样,setTimeout就会被立即执行,而不会等待(这里不太了解细节,就不多说了,大概猜测为新开了一个临时的线程,立即执行匿名函数,然后再立即切换回来)。

本文主要在说明如何解决这一类问题,对于底层原理,还待继续挖掘。

注意:html5支持Web worker功能,可以写多线程。

Js中for循环的阻塞机制的更多相关文章

  1. JS实现停留几秒sleep,Js中for循环的阻塞机制,setTimeout延迟执行

    //第一种,使用while循环 function sleep(delay) { var start = (new Date()).getTime(); while((new Date()).getTi ...

  2. js中的循环语句

    js中的循环语句可分为三种:1.while:2.do……while:3.for. while的语法为 while (exp) {    //statements;} var a=1,b=0; whil ...

  3. js中的循环

    js中的循环是我们经常要用到的,现在进行一些归纳. 一.javascript种的循环. 1.循环对象 var o = { name: 'Jack', age: 20, city: 'Beijing' ...

  4. js中for循环的研究

    转自:http://blog.csdn.net/lushuaiyin/article/details/8541500 <html> <body> <b><ce ...

  5. java和js中for循环的区别

    java中for循环,先执行语句后循环 for (int i=1;i<10;i++){ for(int b=1;b<=i;b++){ System.out.print(b+"*& ...

  6. JS中的循环嵌套 BOM函数

    [嵌套循环特点]                           外层循环转一次,内层循环转一圈              外层循环控制行数,内层循环控制每行元素个数             [做 ...

  7. JS中for循环变量作用域--解决for循环异步执行的问题

    被这个问题困惑了很久,终于在网上找到了答案,感谢~ 现在分享给大家~ js中如何让一个for循环走完之后,再去执行下面的语句? 这涉及for循环变量作用域的问题,js中作用域只有函数作用域和全局作用域 ...

  8. 简单聊一聊JS中的循环引用及问题

    本文主要从 JS 中为什么会出现循环引用,垃圾回收策略中引用计数为什么有很大的问题,以及循环引用时的对象在使用 JSON.stringify 时为什么会报错,怎样解决这个问题简单谈谈自己的一些理解. ...

  9. 实例分析Vue.js中 computed和methods不同机制

    在vue.js中,有methods和computed两种方式来动态当作方法来用的 1.首先最明显的不同 就是调用的时候,methods要加上() 2.我们可以使用 methods 来替代 comput ...

随机推荐

  1. PyQt中对RadioButton分组

    我们知道在同一widget组件中的radio button有排他属性,为了在一个窗口中显示多组radio button,我们需要对其分组. 通常有两种选择,一种是BoxGroup,另一种是Button ...

  2. Javascript中的Trait与代码重用

    Javascript中的Trait与代码重用 来源 http://www.ituring.com.cn/article/64103 我们知道,OOP中最普遍的代码重用方式是通过继承,但是,继承有一些缺 ...

  3. stl中auto_ptr,unique_ptr,shared_ptr,weak_ptr四种智能指针使用总结

    stl中auto_ptr,unique_ptr,shared_ptr,weak_ptr四种智能指针使用总结 1. auto_ptrauto_ptr主要是用来解决资源自动释放的问题,比如如下代码:voi ...

  4. 一场围绕着‘Deeping Learning’的高考

    Deep Learning的基本思想和方法 实际生活中,人们为了解决一个问题,如对象的分类(对象可是是文档.图像等),首先必须做的事情是如何来表达一个对象,即必须抽取一些特征来表示一个对象,如文本的处 ...

  5. Python文件夹备份

    Python文件夹备份 import os,shutil def file_copy(path1,path2): f2 = [filename1 for filename1 in os.listdir ...

  6. vue-cli 前端开发,后台接口跨域代理调试问题

    使用 webpack的方式开发的时候,前台开发过程中需要调用很多后台的数据接口,但是通常前后台分离的开发方式,后台的接口数据很可能是不方便或者是不能在前端同学的电脑上运行的,也就出现了所谓的跨域问题. ...

  7. CSS系列------选择器和选择器的优先级

    1.1.基本选择器 通配符选择器(*)      通配符选择器的使用方法如下 *{margin:0px; padding:0px;} //*代表所有的 ID选择器(#) ID选择器的使用方式如下: * ...

  8. 一款非常推荐的用户界面插件----EasyUI

      前  言    easyui是一种基于jQuery的用户界面插件集合. easyui为创建现代化,互动,JavaScript应用程序,提供必要的功能. 使用easyui你不需要写很多代码,你只需要 ...

  9. JAVA_读取XML文件

    在项目中,很多种情况都需要将一些配置写在xml文件或者properties文件里,便于日后修改配置,好维护等等. 1.新建xml文件 <?xml version="1.0" ...

  10. bootstrap-wysihtml5设置值

    今天做项目的时候用到了 bootstrap-wysihtml5,添加完一篇文章返回去继续添加的时候,js已经设置了将所有变量的值清空,但是不管用$('#someId').val(")还是$( ...