JS魔法堂:初探传说中的setImmediate函数

一、前言                              

   由于JavaScript程序为单线程,因此在执行长时间的操作时(如循环和递归操作)到导致UI线程长期被阻塞,无法响应用户操作请求(如点击按钮等),让用户体验大打折扣。于是想到将一个长时间操作切片成N个小操作并异步执行,例如jsDeferred中的 Deferred.repeat函数 就提供这样的解决办法,其实质就是通过 setTimeout事件  script元素 的 onerror/onload事件 来异步调用这些小操作,从而尽早释放UI线程。

   从IE10开始引入了setImmediate接口来代替setTimeout来完成上述功能,下面将记录该接口的资讯,由于内容会涉及到event loop、调用栈等知识,而我对相关内容了解仍不全面,因此下面的内容若有纰漏请各位指正,谢谢!

二、同步和异步调用                        

  由于JavaScript是通过异步调用来尽早释放UI线程,因此我们先要了解同步和异步执行的具体含义:

  任务的执行实质上分为两步:①.执行,②.获取执行结果。

同步执行:执行后等待直到获取执行结果;

异步执行:执行后不等待,而是通过一系列手段(轮询、事件监听和event loop等)获取执行结果,而在执行后和获取结果前的那段时间可以介入其他任务操作。  

二、setTimeout(handler, 0)的问题                

  由于setTimeout存在时间精度,因此setTimeout(handler,0)中setTimeout事件插入事件队列的延时必定大于0ms,而handler的执行延时则更大了。具体为IE5~8和不插电源的IE9的时间精度为15.6ms,插电源的IE9和其他浏览器则为4ms。

  经微软和Chrome团队实验所得降低时间精度将会大大缩短笔记本的续航时间,也是就说更耗电,因此即使浏览器厂商有能力缩短时间精度,但基于多方面的考虑,依然保持上述的精度值。

三、setImmediate接口                     

  对于通过异步执行的手段对任务切片,由于UI线程得到释放从而提高用户体验,但相对于采用同步执行,整体的任务执行时间较被拉长,因此我们希望切片的小操作越快执行越好。而setImmediate接口则是为此而生的。

setImmediate(handler) 并不像 setTimeout(handler, 0) 由event loop检测系统时间是否到点然后向事件队列插入一个事件,然后调用事件的回调方法handler。而是监控UI线程的调用栈,一旦调用栈为空则将handler压栈。

   理论上通过setImmediate执行异步调用的延时一定比通过setTimeout的短,但事实又是如何呢?

   我在IE11上操作测试,setTimout的延时为4ms左右,而setImmediate的延时为2ms左右。

注意:

     1. 通过setImmediate的异步调用的延时不是0ms哦!

     2. 而且有时候setImmediate的延时比setTimeout的多1~2ms哦!

     3. 而且setImmediate和setTimeout的延时均比img元素onerror事件的延时长哦!

  推测:

     1. 对于setImmediate的延时有时比setTimeout的要长,由于setImmediate要先监控调用栈,若调用栈为空才压栈,那么在压栈之前event loop已经将setTimeout事件的回调函数压栈了。

     2. 对于两者均比img元素onerror事件的长,由于设置img.src后马上发起请求(不一定为网络IO)当加载失败时onerror事件则会比setTimeout事件先加入事件队列。

四、总结                            

  本文内容纰漏之处请各位指正,谢谢!

五、参考                            

  http://developer.51cto.com/art/201109/292720.htm

  http://msdn.microsoft.com/library/ie/hh920766.aspx

  https://github.com/yuzujs/setimmediate

  http://www.nczonline.net/blog/2011/09/19/script-yielding-with-setimmediate/

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏ionic3+

【开发指南】(四)Ionic3快速上手并了解这些

Ionic这几个网站是需要经常看的,应该了解过才执行后面步骤,其中强烈要求至少先撸一遍官网的组件和API文档。

852
来自专栏西安-晁州

vue.js学习之入门实例

之前一直看过vue.js官网api,但是很少实践,这里抽出时间谢了个入门级的demo,记录下一些知识点,防止后续踩坑,牵扯到的的知识点:vue、vue-cli、...

2330
来自专栏魏艾斯博客www.vpsss.net

宝塔 Linux 面板 3.X/4.x 忘记密码解决方法

3482
来自专栏知晓程序

开发 | 简单易上手,资讯类小程序开发实战指南

今天,知晓程序(微信号 zxcx0101)将通过一个简单的电影资讯小程序,来看看在知晓云内容库功能的帮助下,如何将内容资讯类小程序的开发效率提高 60%。

1531
来自专栏魏琼东

.NET快速开发实践之应用IExtenderProvider实现对象与UI控件的绑定

         现在企业级的信息系统应用开发之中,数据层采用了ORM,解放了之前开发最大工作量的核对SQL语句,我到现在还曾经记得在2002年实医院管理信息系...

2056
来自专栏前端儿

Fiddler使用AutoResponder进行本地文件和线上文件的映射

就捞起尘封已久的 Fiddler,既然线上的JQ加载不出来,那就做个本地文件的映射吧,使用本地的JQ库代替线上的

1171
来自专栏王磊的博客

VueJs开发笔记—IDE选择和优化、框架特性、数据调用、路由选项及使用

一、IDE的选择:   VsCode和WebStorm都是不错的选择,说一下两者的优缺点,调试便捷性来说两者不相上下.   WebStorm缺点:性能方面VsC...

4135
来自专栏蔡述雄的专栏

包学会之浅入浅出Vue.js:开学篇

Vue 是国人写的,技术文档也妥妥的是中文,想到这我就有学习的动力。

49.9K66
来自专栏Danny的专栏

html页面导出为pdf(jsPDF、iText、wkhtmltopdf)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huyuyang6688/article/...

1.5K1
来自专栏DeveWork

WordPress 添加个性化的博客宠物(妹纸篇)

某日闲逛看到的某个博客上的一个博客宠物,准确来说不是宠物,人家可是萌妹纸啊!看看右侧这个图,就是这个萌妹纸了(后来用谷歌相似图片搜索才发现是死亡笔记的)。让我感...

2705

扫码关注云+社区

领取腾讯云代金券