JS是单线程引擎:它把任务放到队列中,不会同步去执行,必须在完成一个任务后才开始另外一个任务。

浏览器的内核是多线程的,它们在内核制控下相互配合以保持同步,一个浏览器至少实现三个常驻线程:javascript引擎线程,GUI渲染线程,浏览器事件触发线程。

  • javascript引擎是基于事件驱动单线程执行的,JS引擎一直等待着任务队列中任务的到来,然后加以处理,浏览器无论什么时候都只有一个JS线程在运行JS程序。
  • GUI渲染线程负责渲染浏览器界面,当界面需要重绘(Repaint)或由于某种操作引发回流(reflow)时,该线程就会执行。但需要注意 GUI渲染线程与JS引擎是互斥的,当JS引擎执行时GUI线程会被挂起,GUI更新会被保存在一个队列中等到JS引擎空闲时立即被执行。
  • 事件触发线程,当一个事件被触发时该线程会把事件添加到待处理队列的队尾,等待JS引擎的处理。这些事件可来自JavaScript引擎当前执行的代码块如setTimeOut、也可来自浏览器内核的其他线程如鼠标点击、AJAX异步请求等,但由于JS的单线程关系所有这些事件都得排队等待JS引擎处理。(当线程中没有执行任何同步代码的前提下才会执行异步代码)

利用setTimeout(fn,0)的特性,可以帮助我们在某些极端场景下,修正浏览器的下一个任务。

JavaScript的setTimeout与setInterval是两个很容易欺骗别人感情的方法,因为我们开始常常以为调用了就会按既定的方式执行, 我想不少人都深有同感, 例如

setTimeout( function(){ alert(’你好!’); } , 0);
setInterval( callbackFunction , 100);

认为setTimeout中的问候方法会立即被执行,因为这并不是凭空而说,而是JavaScript API文档明确定义第二个参数意义为隔多少毫秒后,回调方法就会被执行. 这里设成0毫秒,理所当然就立即被执行了.
同理对setInterval的callbackFunction方法每间隔100毫秒就立即被执行深信不疑!

但随着JavaScript应用开发经验不断的增加和丰富,有一天你发现了一段怪异的代码而百思不得其解:

div.onclick = function(){
setTimeout( function(){document.getElementById(’inputField’).focus();}, 0);
};

既然是0毫秒后执行,那么还用setTimeout干什么, 此刻, 坚定的信念已开始动摇.

直到最后某一天 , 你不小心写了一段糟糕的代码:

setTimeout( function(){ while(true){} } , 100);
setTimeout( function(){ alert(’你好!’); } , 200);
setInterval( callbackFunction , 200);

第一行代码进入了死循环,但不久你就会发现,第二,第三行并不是预料中的事情,alert问候未见出现,callbacKFunction也杳无音讯!

这时你彻底迷惘了,这种情景是难以接受的,因为改变长久以来既定的认知去接受新思想的过程是痛苦的,但事实摆在眼前。

事实上的,JavaScript使用了障眼法,在多数时候骗过了我们的眼睛,这里背光得澄清一个事实:

JavaScript引擎是单线程运行的,浏览器无论在什么时候都只且只有一个线程在运行JavaScript程序.

第一行代码永远的占用了JS线程,所以后面的无法再执行。

setTimeout( function(){ while(true){} } , 100);
setTimeout( function(){ alert(’你好!’); } , 0);

setTimeout(fn,0)可调整JS线程执行的顺序,插入到当前执行,即可alert出 你好! 但是第一行代码还是会一直执行。

原文参考:  https://www.cnblogs.com/silin6/p/4333999.html

https://blog.csdn.net/kongls08/article/details/6996518

最新文章

  1. h264 profile & level
  2. iTween研究院之学习笔记Move移动篇
  3. echsop常用模板方法.
  4. c#操作文件夹得读写权限
  5. 最新做路径动画必备Simple Waypoint System5.1.1最新做路径动画必备Simple Waypoint System5.1.1
  6. Java框架篇---Mybatis 构建SqlSessionFactory
  7. C++十进制转换为二进制
  8. ADB 远程无线调试
  9. Nginx缓存解决方案:SRCache
  10. 表单属性问题readonly、disabled、checked,prop的使用
  11. RoboCup仿真3D TC笔记(2014年合肥中国公开赛 仿真3D比赛环境搭建)
  12. python实现类jq的json路径过滤
  13. UEP-弹窗
  14. C# 多线程编程,传参,接受返回值
  15. Linux下DHCP服务安装配置
  16. 即将上线的Spark服务器面临的一系列填坑笔记
  17. linux软链接和硬链接的区别
  18. 前端框架VUE----es6简单介绍
  19. log4j的基本使用方法
  20. 【北京】安全研究员/工程师-20-35K,人体工程学座椅坐等你来~

热门文章

  1. ES6 Fetch API HTTP请求实用指南
  2. openocd+jlink为mini2440调试u-boot
  3. Android开发学习之三——第一个Android程序
  4. hihocoder #1052 : 基因工程(字符串处理 + 找规律 )
  5. python3 - 写一个生成双色球号码的一个程序,生成的号码写到文件里面
  6. ACM学习历程——HDU4472 Count(数学递推) (12年长春区域赛)
  7. 监测GPU使用情况命令
  8. 数据结构与算法(3)----->队列和栈
  9. bzoj 4453 cys就是要拿英魂! —— 后缀数组+单调栈+set
  10. POJ1195(二维树状数组)