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的语法同样.它们都有两个參数.一个是将要运行的代码字符串.另一个是以毫秒为单位的时间间隔,当过了那个时间段之后就将运行那段代码. 只是这两个函数还是有差别的 ...
随机推荐
- 不可或缺 Windows Native (15) - C++: 命名空间
[源码下载] 不可或缺 Windows Native (15) - C++: 命名空间 作者:webabcd 介绍不可或缺 Windows Native 之 C++ 命名空间 示例CppNamespa ...
- 项目中初试PHP单元测试
只能叫初试,前面虽然做了一些PHPUnit与团队所用框架的整合,但在整个团队还没有人可以主动推动这个事情,而作为Leader最重要的一种能力应该是"让正确的事情发生",所以今天开始 ...
- springmvc(3)拦截器HandlerInterceptor源码的简单解析
其实拦截器就是我们的AOP编程.拦截器在我们的实际项目中实用性比较大的,比如:日志记录,权限过滤,身份验证,性能监控等等.下面就简单的来研究一下拦截器: public interface Handle ...
- 第 18 章 CSS 表格与列表
学习要点: 1.表格样式 2.列表样式 3.其他功能 主讲教师:李炎恢 本章主要探讨 HTML5 中 CSS 表格和列表,通过表格和列表的样式设置,让表格和列表显示更加多元化. 一.表格样式 表格有五 ...
- Array数组基础
数组的定义 数组(array)是按次序排列的一组值,单个值称为元素,它们的位置都有编号(从0开始).整个数组用方括号表示. var arr = ['a', 'b', 'c']; 上面代码中的a.b.c ...
- Java关于Properties用法的总结(一)
最近项目中有一个这样的需求,要做一个定时任务功能,定时备份数据库的操表,将表数据写入txt文件.因为文件的读写路径可能需要随时改动,所以写死或者写成静态变量都不方便,就考虑使用配置文件,这里总结些配置 ...
- EntityFramework动态多条件查询与Lambda表达式树
在常规的信息系统中, 我们有需要动态多条件查询的情况, 例如UI上有多个选择项可供用户选择多条件查询数据. 那么在.net平台Entity Framework下, 我们用Lambd ...
- Awesomplete - 零依赖的简单自动完成插件
Awesomplete 是一款超轻量级的,可定制的,简单的自动完成插件,零依赖,使用现代化标准构建.你可以简单地添加 awesomplete 样式,让它自动处理(你仍然可以通过指定 HTML 属性配置 ...
- 【干货分享】32本优秀的 JavaScript 免费电子书
JSbooks 收集了32本优秀的 JavaScript 免费电子书,分为初级.中级.高级三个类比,大家可以根据自身的情况需要下载.实实在在的干货!记得收藏和分享啊:) 您可能感兴趣的相关文章 Ver ...
- requirejs:杏仁的优化(almond)
这里只是调侃一下,“杏仁”其实指的是almond,requirejs作者的另一个开源项目,它的定位是作为requirejs的一个替代品. 本文概要: 1. 使用场景 2. 打包例子:未使用almond ...