Javascript之旅——终点站:困惑的settimeout
有时候结局不是很美好,但起码这也算是一种结局,这个系列的最后一篇settimeout,这是一个让人困惑的函数,也是我一直在吐槽JS的
原因,我们看不到JS的源代码,setimeout同样也是,从始到终都是黑盒子的使用。
一:settimeout单线程的质疑?
所有的教科书都在说js是单线程模型,也说settimeout的执行函数会丢给js的内部执行队列,这其中还包括onlick事件以及一些xhr的回调函数。
乍一看貌似是这么一回事,既然要排队嘛,那肯定是FIFO的原则了,谁也无法保证准确的定时触发,就算精确的触发的,也不能保证在执行队列中
马上执行,因为要排队,如果我设定了5s触发,所以时间一定会在5s 以上,问题就出现在这里,这个5s触发的机制是什么样的???谁能告诉我
呢????既然js是单线程的,难道是js会不停的轮训“执行队列”吗?问执行函数5s时间到了吗?5s时间到了吗???我想JS肯定不会这么傻乎乎
做这么个“内旋”操作,因为如果我设定的触发时间是1年呢?难道还要内旋1年么???而且这种拉模式是相当耗费CPU时间的,那为了尽量节省
CPU的时间,是否会有其他线程来辅助setttimeout来做这个5s的机制呢?然后5s时间到了将setimeout中的执行函数推入js的内部执行队列呢?
到底合理的方式会是怎么样的?
二:在System.Threading.Timer中寻找灵感
因为setimeout的闭源,我看不到settimeout内部到底怎么做到5s触发的机制,非常遗憾,我也只能去找类似语言中的Timer机制,还好在C#
中也是有这样的一个定时器,看看能不能找到些灵感,然后我就大概看了下源码:
static void Main(string[] args)
{
System.Threading.Timer timer = new System.Threading.Timer(Run, "", , * * ); //30s Console.Read();
}

通过眼花缭乱的查找,终于明白,原来Timer仅仅是对一个Win32中CreateAppDomainTimer函数的封装,真是他们的坑货,先让你眼见为实。

其中的dueTime也就是我的Timer构造函数中的period参数,这里也就是30s,然后定时触发AppDomainTimerCallback函数,一段逻辑后再调用
Fire方法触发我们的CallCallback函数。



其实我们看到源码之后,发现Timer计时器其实是个假的,只是封装了Win32函数,并且也没有做到完完全全的30s,这是因为callback()是在调用
AppDomainTimerCallback函数之后触发的,这些逻辑也是需要耗费时间的,包括win32回调的误差,那现在有什么灵感呢?既然C#的多线程采用
工作线程去跑都有误差,那你单线程的settimeout又何德何能呢?那更不用谈用主线程去轮训settimeout这个很不现实的东西。
三:最后的一点猜测
通过对C#中的Timer原理的一些理解,我觉得settimeout应该是这样的,这其中的5s机制应该是丢给浏览器内核线程了,由浏览器内核线程去实
现这个5s的机制,如果5s时间到了,内核会将function函数塞给js的“内部执行队列”,由js主线程空闲的时候去得以执行。毕竟浏览器线程还是有很多
的,比如下面的IE9:

好了,不说了,说的再多也是猜测,结局并不完美,感谢大家对javascript系列的持续关注,也祝大家在新的一年工作顺利~~~
Javascript之旅——终点站:困惑的settimeout的更多相关文章
- JavaScript之旅(DOM)
JavaScript之旅(DOM) [TOC] 一.认识DOM 什么是 DOM? DOM 是 Document Object Model(文档对象模型)的缩写. DOM 是 W3C(万维网联盟)的标准 ...
- JavaScript之旅(三)
JavaScript之旅(三) 三.函数 在JavaScript中,定义函数的方式如下: function abs(x) { ... return ...; } 如果没有return,返回结果为und ...
- JavaScript之旅(二)
JavaScript之旅(二) 二.进阶知识 js的正则表达式 异常处理 调试 变量提升 表单验证 JSON javascript:void(0) JavaScript 代码规范 二.进阶知识 1. ...
- Javascript之旅(一)
Javascript之旅(一) 一.基础知识 基本语法 变量 数据类型 字符串 数组 对象 条件判断 循环 Map和Set iterable 为什么要学习JavaScript JavaScript 是 ...
- JavaScript DOM 编程艺术·setInterval与setTimeout的动画实现解析
先贴上moveElement()函数的大纲,为了方便观看,删了部分代码,完整版粘到文章后面. function moveElement(elementID,final_x,final_y,interv ...
- JavaScript之关闭轮询定时器(setTimeout/clearTimeout|setInterval/clearInterval)小结
已知: 1.1 开启Timeout程序: scope.setTimeout("functionName()" | functionHandle, timeValue) 返回值:ti ...
- JavaScript你所不知道的困惑(2)
困惑一: var obj1 = new Object(); var obj2 = obj1; obj1.name = "阳光小强"; alert(obj2.name); //输出结 ...
- JavaScript你所不知道的困惑(1)
困惑一: 先看一个样例: function test(){ message = "hi"; } test(); alert(message); 会输出字符串"hi&quo ...
- JavaScript定时调用函数(SetInterval与setTimeout)
setTimeout和setInterval的语法同样.它们都有两个參数.一个是将要运行的代码字符串.另一个是以毫秒为单位的时间间隔,当过了那个时间段之后就将运行那段代码. 只是这两个函数还是有差别的 ...
随机推荐
- 使用C#向Sql Sever中存取网络图片和本地图片(二进制流的形式)
先是做普通的,存储我们本地的图片,将它转化为二进制流存储到数据库对应的表中. 代码如下: string path = "../../A.jpg"; FileStream fs = ...
- 为sql server 增加 parseJSON 和 ToJSON 函数
在SqlServer中增加Json处理的方法 Sql Server 存储非结构话数据可以使用xml类型,使用xpath方式查询,以前写过一篇随笔:Sql Server xml 类型字段的增删改查 除了 ...
- 双系统下删除Linux系统方法和Windows无法启动问题的解决方法
装了一个linux,后面直接把它删掉了,结果电脑重启的时候重启不了,总是一开机就出现 grub> 心中无比的恼火,后面想不通了,就打算直接重装系统,结果重装系统的过程中遇到了问题,B ...
- 使用PDF.JS在线查看PDF
过程简单粗暴. 第一步:下载源码https://github.com/mozilla/pdf.js 第二步:将源码拷贝进项目中,可以新建一个PDFShow文件夹存放代码 第三步:修改viewer.js ...
- PHP替代正则匹配的高效函数
strpos() - 查找字符串首次出现的位置 strrpos() 函数查找字符串在另一字符串中最后一次出现的位置(区分大小写). strripos() 函数查找字符串在另一字符串中最后一次出现的位置 ...
- cnodejs社区论坛5--话题详情
- mesos 学习笔记1 -- mesos安装和配置
参考资料: 官方文档:http://mesos.apache.org/documentation 中文翻译:http://mesos.mydoc.io/ GitHub:https://github.c ...
- 【笔记】InnoDB内存分配
原文:http://www.mysqlperformanceblog.com/2006/05/30/innodb-memory-usage/ 有很多问题是有关InnoDB如何分配内存的.这里我试图解释 ...
- jQuery Flat Shadow – 轻松实现漂亮的长阴影效果
长阴影其实就是扩展了对象的投影,感觉是一种光线照射下的影子,通常采用角度为 45 度的投影,给对象添加了一份立体感.长阴影快速发展为流行的设计趋势,并经常被应用到扁平设计方案的对象.更详细的介绍可以阅 ...
- Scroll Depth – 衡量页面滚动的 Google 分析插件
Scroll Depth 是一个小型的 Google Analytics(谷歌分析)插件,可以让你衡量用户在页面上滚动了多远.它可以监控 25%.50%.75% 和 100% 四个滚动点,并发送谷歌分 ...