关于setTimeout(fn,0)
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
最新文章
- h264 profile &; level
- iTween研究院之学习笔记Move移动篇
- echsop常用模板方法.
- c#操作文件夹得读写权限
- 最新做路径动画必备Simple Waypoint System5.1.1最新做路径动画必备Simple Waypoint System5.1.1
- Java框架篇---Mybatis 构建SqlSessionFactory
- C++十进制转换为二进制
- ADB 远程无线调试
- Nginx缓存解决方案:SRCache
- 表单属性问题readonly、disabled、checked,prop的使用
- RoboCup仿真3D TC笔记(2014年合肥中国公开赛 仿真3D比赛环境搭建)
- python实现类jq的json路径过滤
- UEP-弹窗
- C# 多线程编程,传参,接受返回值
- Linux下DHCP服务安装配置
- 即将上线的Spark服务器面临的一系列填坑笔记
- linux软链接和硬链接的区别
- 前端框架VUE----es6简单介绍
- log4j的基本使用方法
- 【北京】安全研究员/工程师-20-35K,人体工程学座椅坐等你来~
热门文章
- ES6 Fetch API HTTP请求实用指南
- openocd+jlink为mini2440调试u-boot
- Android开发学习之三——第一个Android程序
- hihocoder #1052 : 基因工程(字符串处理 + 找规律 )
- python3 - 写一个生成双色球号码的一个程序,生成的号码写到文件里面
- ACM学习历程——HDU4472 Count(数学递推) (12年长春区域赛)
- 监测GPU使用情况命令
- 数据结构与算法(3)----->;队列和栈
- bzoj 4453 cys就是要拿英魂! —— 后缀数组+单调栈+set
- POJ1195(二维树状数组)