博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
深入理解JavaScript定时器
阅读量:7120 次
发布时间:2019-06-28

本文共 1505 字,大约阅读时间需要 5 分钟。

对于浏览器内部,大部分操作都是异步的生成事件并添加到JavaScript引擎线程的队列中,然后由JavaScript引擎线程进行调度执行。因此浏览器的很多事件都是和JavaScript相结合的,但是也有一些内部的限制。

首先我们非常确定JavaScript是单线程的,对于浏览器来说,一个窗体中只有一个JavaScript引擎线程。而其他的行为,如:渲染、下载等是由单独的线程进行管理的,且具有不同的优先级。

异步事件

前面提到大多数事件都是异步的,触发的时候就将回调函数添加到事件队列。浏览器提供了一个内部的回路,也就是之前所谈到的Event Loop,由它来负责检查队列和处理事件、执行函数等。详细可参考我的。而setTimeoutsetInterval也是将其需要执行的函数添加到事件队列。

事实上,大多数交互和活动都得通过事件循环。

事件重叠

一些情况下,会有多个事件在同一时间附加到事件队列里。

比如,click事件就会产生两个额外的事件:mousedownmouseup。其中,mouseupclick事件会同时被添加到事件队列;而mousedown事件则很有可能会和另外一个事件重叠:focus

setTimeout(func, 0)奇巧淫技

再一次解释关于0ms的误解:如果当前时钟周期内执行队列空闲,则立即执行该定时器,将回调函数加入到事件队列;然后等待下一个时钟周期,再执行该回调函数。不妨来看看下面的测试。

这段代码在我的浏览器中执行结果如下:

在我本地的Nodejs环境中执行结果如下:

上面的这个测试只是想说明setTimeout(func, 0)定时任务的回调函数执行时间是有延迟的,而并不是所谓的立即执行。

因此,我们可以利用setTimeout(func, 0)来解决事件重叠所产生的负面效果,修正执行顺序。

奇巧淫技之一:模拟浏览器的事件捕获

众所周知,浏览器的DOM事件都是采用冒泡的方式,只有个别浏览器是支持事件捕获的。而在实际的开发过程中可能存在需要事件捕获的需求,要求子元素的事件在父元素触发之后才能触发。为了兼容各个浏览器,我们不能使用事件捕获,而setTimeout(func, 0)在这个时候就很乐意帮忙了。

 

12345678910111213141516

点击查看运行效果:

 

奇巧淫技之二:让浏览器更好的工作

大多数情况下,我们可以在浏览器的默认行为之前对事件进行处理,但是有时我们按照常规的思路去做的时候,往往事与愿违。比如下面的例子。

 

1234567

看似一个很简单的需求:每输入一个字符,就将其转换为大写。但是上面的代码完全没有按照指示去做,不信你试试看:

 

如果没有下一次输入,文本框中的小写字母永远都不会转换为大写。Why? 因为浏览器在keypress事件处理的时候,还没有将我们输入的值添加到文本框。于是乎换一个事件来handle然后再处理吧,既然键按下的时候还木有值,那就等键弹起来之后再处理。

 

1234567

运行试试吧。

 

大概似乎是可行了,可是仔细观察就看出问题了。keyup事件触发时,文本框已经具备完整的值了,但先是一个小写的值,键完全释放之后转变为大写。这不科学…这太丑陋...

是时候关门放出setTimeout(func, 0)了。。。

 

12345678910

 

已经完美了。keypress事件触发时,将转换大写的操作添加到事件队列,紧接着浏览器添加我们输入的值,然后近乎0延迟的执行我们的转换大写操作函数。

上面两个小案例只是冰山一角,so...合理利用setTimeout(func, 0),明天更美好!

转载地址:http://fpxel.baihongyu.com/

你可能感兴趣的文章
我的iOS程序生涯的起点
查看>>
程序员的工匠精神
查看>>
【underscore.js 源码解读】for ... in 存在的浏览器兼容问题你造吗
查看>>
Sass 与 Compass 实战经验总结
查看>>
微信公众号开发小记——3.接入三方登录
查看>>
个推获7亿元C轮募资,SDK接入超80亿
查看>>
如何10分钟让APP实现实时互动?
查看>>
Consul入门01 - 安装Consul
查看>>
Swift 编程思想,第一部分(补遗):牺牲小马
查看>>
css 不规整元素的宽高等比例
查看>>
let vs const
查看>>
Swift里你可能不知道的事儿(2)——处理对象reference cycle的三种方式
查看>>
聊聊json
查看>>
【更新】FusionCharts图表库 v3.10.0发布|附下载
查看>>
Python async/await Tutorial(翻译)
查看>>
TensorFlow实战之K-Means聚类算法实践
查看>>
verify.js 极简表单校验插件
查看>>
调查显示,大多数 Java 开发人员不希望学习新语言
查看>>
华为诉美国政府案新进展,法院已发传票
查看>>
小米成立AIoT战略委员会,加速落地All in AIoT战略 ...
查看>>