当前栏目
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#
中也是有这样的一个定时器,看看能不能找到些灵感,然后我就大概看了下源码:
1 static void Main(string[] args) 2 { 3 System.Threading.Timer timer = new System.Threading.Timer(Run, "", 0, 1000 * 30 * 1); //30s 4 5 Console.Read(); 6 }
通过眼花缭乱的查找,终于明白,原来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系列的持续关注,也祝大家在新的一年工作顺利~~~
相关文章
- Node中导入模块require和import??
- vuejs 入门
- Node.js用fs.renameSync报cross-device link not permitted错
- Node入门
- 微信开发——测试号申请,接口配置,JS接口安全域名,自定义菜单
- js知识点
- reduxjs-toolkit 案例 — 登录
- ListNode算法
- js 大文件上传的思路
- 前端高薪必会的JavaScript重难点知识:防抖与节流详解
- 用javascript分类刷leetcode4.贪心(图文视频讲解)
- JavaScript刷LeetCode拿offer-js版字典
- js二叉树层序遍历
- JavaScript:this是什么?
- JS IOS/iPhone的Safari不兼容Javascript中的Date()问题
- PHP中把数据库查询结果输出为json格式
- javascript/jquery获取地址栏url参数的方法
- js中window.location的用法
- jQuery升级踩坑之路
- javascript正则表达式总结(test|match|search|replace|split|exec)