微信号:FrontDev

介绍:分享 Web 前端相关的技术文章、工具资源、精选课程、热点资讯

Javascript之旅——终点站:困惑的settimeout

2015-02-25 20:44 前端大全
点击上方蓝字↑↑↑,轻松关注哦~

有时候结局不是很美好,但起码这也算是一种结局,这个系列的最后一篇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, "", 0, 1000 * 30 * 1); //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系列的持续关注,也祝大家在新的一年工作顺利~~~




来自:一线码农的博客

链接:http://www.cnblogs.com/huangxincheng/p/4199734.html



/////////////////


1. 『前端大全』分享 Web 前端相关的技术文章、工具资源、精选课程、热点资讯,欢迎关注。微信号:FrontDev

(长按二维码↑↑↑自动可扫描)

http://web.jobbole.com/all-posts/

2. 点击“阅读原文”,查看更多前端文章。


 
前端大全 更多文章 5个典型的JavaScript面试题(上) Limu:JavaScript的那些书 Web开发:我希望得到的编程学习路线图 JavaScript基础工具清单 常用排序算法之JavaScript实现
猜您喜欢 阿里百川:OneSDK与手机淘宝技术能力开放 Swift 必备开发库 (高级篇) 用Python做自然语言处理必知的八个工具 Java开发必会的Linux命令 不要让华为跑了?华为回应:没打算跑。但感觉也差不多