一、前言                              

由于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, ) 由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://www.cnblogs.com/fsjohnhuang/p/4151595.html ^_^肥仔John

五、参考                            

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/

JS魔法堂:初探传说中的setImmediate函数的更多相关文章

  1. JS魔法堂:不完全国际化&本地化手册 之 实战篇

    前言  最近加入到新项目组负责前端技术预研和选型,其中涉及到一个熟悉又陌生的需求--国际化&本地化.熟悉的是之前的项目也玩过,陌生的是之前的实现仅仅停留在"有"的阶段而已. ...

  2. JS魔法堂:判断节点位置关系

    一.前言 在polyfill querySelectorAll 和写弹出窗时都需要判断两个节点间的位置关系,通过jQuery我们可以轻松搞定,但原生JS呢?下面我将整理各种判断方法,以供日后查阅. 二 ...

  3. JS魔法堂:IMG元素加载行为详解

    一.前言 在<JS魔法堂:jsDeferred源码剖析>中我们了解到img元素加载失败可以作为函数异步执行的优化方案,本文打算对img元素的加载行为进行更深入的探讨. 二.资源加载的相关属 ...

  4. JS魔法堂:jsDeferred源码剖析

    一.前言 最近在研究Promises/A+规范及实现,而Promise/A+规范的制定则很大程度地参考了由日本geek cho45发起的jsDeferred项目(<JavaScript框架设计& ...

  5. JS魔法堂:属性、特性,傻傻分不清楚

    一.前言 或许你和我一样都曾经被下面的代码所困扰 var el = document.getElementById('dummy'); el.hello = "test"; con ...

  6. JS魔法堂:那些困扰你的DOM集合类型

    一.前言 大家先看看下面的js,猜猜结果会怎样吧! 可选答案: ①. 获取id属性值为id的节点元素 ②. 抛namedItem is undefined的异常 var nodes = documen ...

  7. JS魔法堂:精确判断IE的文档模式by特征嗅探

    一.前言 苦逼的前端攻城狮都深受浏览器兼容之苦,再完成每一项功能前都要左顾右盼,生怕浏览器不支持某个API,生怕原生API内含臭虫因此判断浏览器类型和版本号成了不可绕过的一道关卡,而特征嗅探是继浏览器 ...

  8. JS魔法堂:追忆那些原始的选择器

    一.前言                                                                                                 ...

  9. JS魔法堂:不完全国际化&本地化手册 之 理論篇

    前言  最近加入到新项目组负责前端技术预研和选型,其中涉及到一个熟悉又陌生的需求--国际化&本地化.熟悉的是之前的项目也玩过,陌生的是之前的实现仅仅停留在"有"的阶段而已. ...

随机推荐

  1. 分享:写了一个 java 调用 C语言 开发的动态库的范例

    分享:写了一个 java 调用 C语言 开发的动态库的范例 cfunction.h   代码#pragma once#ifdef __cplusplusextern "C" {#e ...

  2. Android前端人员与后台开发的撕逼(一)

    首先表明一下身份,本人是Android前端开发人员,本篇只做合理性探讨,不进行人身攻击: 其次希望各位大神进行点评!点评!点评! 我们讨论一下接口的两种返回方式,直接举例说明一下,假设书籍信息表有30 ...

  3. 使用statsd+graphite+grafana构建业务及性能监控模块

    近些年随着DevOps概念越来越收到重视,除了传统的Splunk,Zabbix外在开源领域也有越来越多的软件可供使用.从数据收集,时序数据库,图形展示等主要方面有各类可扩展的软件用于搭建一个数据监控平 ...

  4. 【Bugly干货分享】手把手教你逆向分析 Android 程序

    很多人写文章,喜欢把什么行业现状啊,研究现状啊什么的写了一大通,感觉好像在写毕业论文似的,我这不废话,先直接上几个图,感受一下. 第一张图是在把代码注入到地图里面,启动首页的时候弹出个浮窗,下载网络的 ...

  5. C# Lambda表达式详解,及Lambda表达式树的创建

    最近由于项目需要,刚刚学完了Action委托和Func<T>委托,发现学完了委托就必须学习lambda表达式,委托和Lambda表达式联合起来,才能充分的体现委托的便利.才能使代码更加简介 ...

  6. 了解一下JavaScript的未来——ECMAScript5

    神马是EcmaScript5 首先得先搞清楚ECMAScript是神马,我们知道JavaScript或者说LiveScript最开始是Netscape搞出来的,后来微软也跟进搞出了Jscript,Sc ...

  7. 关于QCon2015感想与反思

    QCon2015专场有不少关于架构优化.专项领域调优专题,但能系统性描述产品测试方向只有<携程无线App自动化测试实践>.   (一). 携程的无线App自动化     <携程无线A ...

  8. python Web开发框架-Django (2)

    接上篇文章,介绍一些实用的技巧和注意点.首次用MarkDown编辑,感觉行空隙太大,不是那么好看. GET/POST 前后端会有数据交互,使用JQuery来实现get/post请求 GET 方法1:通 ...

  9. SQL-truncate && delete && drop 的区别

    有些人在删除表的所有记录的时候,喜欢这样来——不给DELETE 语句提供WHERE 子句,表中的所有记录都将被删除.但这种方法是不可取的,正确的应该使用 TRUNCATE TABLE tb_name ...

  10. jmx完整示例

    很早就开始去了解这个了,不过一直都是皮毛,基本概念明白,具体api几乎一无不知... 认真看了几篇文章,做了测试,终于有所了解 参考 入门级别: http://www.cnblogs.com/agou ...