前言
本文主要给大家介绍了关于setTimeout时间设置为0的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。
1、开胃菜,setTimeout为何物
首先看一下w3school上面对于setTimeout的解释
setTimeout(fn,millisec) 方法用于在指定的毫秒数后调用函数或计算表达式。
很简单,setTimeout() 只执行 fn 一次,到底什么时候执行取决于第二个参数millisec设定的毫秒数,所以很多人习惯上称之为延迟,无非就是延迟一段时间后再执行里面的代码。
setTimeout(function(){ console.log('我是setTimeout'); }, 1000);
正常情况下,我是setTimeout 这句话并不会马上输出而是等1000毫秒以后会在浏览器的控制台输出。
2、主菜,js是单线程的
OK,看一个例子,这个例子的输出结果是什么?
setTimeout(function(){ console.log(1); }, 0); console.log(2); console.log(3);
出乎一些人的意料,得到的结果竟然是2、3、1。这似乎不按套路出牌啊,明明是等待了0毫秒也就是不等待直接输出啊,为啥1却在最后输出了呢?
这就需要搞清楚一个很重要的概念:js是单线程的,单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。如果前一个任务耗时很长,后一个任务就不得不一直等着。
其实很好理解,就像大家去超市买东西一样,所有买东西的人都需要在收银台排队结账,正常情况下每个收银台同一时间只能为一位顾客结账,这位顾客结账完成才能为下一位顾客服务。
而浏览器的内核是多线程的,它们在内核制控下相互配合以保持同步,一个浏览器至少实现三个常驻线程:javascript引擎线程,GUI渲染线程,浏览器事件触发线程。
其实,当js代码执行遇到setTimeout(fn,millisec)时,会把fn这个函数放在任务队列中,当js引擎线程空闲时并达到millisec指定的时间时,才会把fn放到js引擎线程中执行。
setTimeout(fn,0)的含义是,指定某个任务在主线程最早可得的空闲时间执行,也就是说,尽可能早得执行。它在"任务队列"的尾部添加一个事件,因此要等到同步任务和"任务队列"现有的事件都处理完,才会得到执行。
HTML5标准规定了setTimeout()的第二个参数的最小值(最短间隔),不得低于4毫秒,如果低于这个值,就会自动增加。在此之前,老版本的浏览器都将最短间隔设为10毫秒。另外,对于那些DOM的变动(尤其是涉及页面重新渲染的部分),通常不会立即执行,而是每16毫秒执行一次。这时使用requestAnimationFrame()的效果要好于setTimeout() 。
需要注意的是,setTimeout()只是将事件插入了"任务队列",必须等到当前代码(执行栈)执行完,主线程才会去执行它指定的回调函数。要是当前代码耗时很长,有可能要等很久,所以并没有办法保证,回调函数一定会在setTimeout()指定的时间执行。
3、甜品,setTimeout的妙用
其实setTimeout是有一些妙用的,这里简单列举几个。
函数去抖
让一个函数在一定间隔内没有被调用时,才开始执行被调用方法。比如当你在使用 google 搜索内容的时候,有些关键词输入到一半,谷歌会展示一个可选列表,根据你当前输入的内容作出的一个猜测联想。需要监听文字改变,每一次改变都会调用一次回调函数,现在需要的一种实现是在用户停止键盘事件一段时间后,去发送一个请求。
var debounce = function(method, context) { clearTimeout(method.tId); method.tId = setTimeout(function(){ method.call(context); },100); }
轮训任务
js中可以使用setInterval开启轮询,但是这种存在一个问题就是执行间隔往往就不是你希望的间隔时间。
比如有个轮询任务间隔是100ms,但是执行方法的时间需要450ms,那么在200ms、300ms、400ms本来是计划中执行任务的时间,浏览器发现第一个还未执行完,那么就会放弃2、3、4次的任务执行,并且在500ms之后再次执行任务,这样的话,其实再次执行的间隔就只有50ms。使用setTimeout构造轮询能保证每次轮询的间隔。
setTimeout(function () { console.log('我被调用了'); setTimeout(arguments.callee, 100); }, 100);
延迟js引擎的调用
var div = document.createElement('div'); div.innerHTML = '我是一个div'; div.setAttribute('style', 'width:200px; height:200px;background-color:#f00; '); document.body.appendChild(div); setTimeout(function() { console.log('我被调用了'); }, 1000);
虽然setTimeout有一些妙用,但是他确实是在宏观任务队列中新增任务了,所以万万不能滥用啊。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对小牛知识库的支持。
本文向大家介绍JavaScript定时器setTimeout()和setInterval()详解,包括了JavaScript定时器setTimeout()和setInterval()详解的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了JavaScript定时器的具体方法,供大家参考,具体内容如下 1、 超时调用setTimeout() 顾名思义,超时调用的意思就是在一段实际之后调用(
问题内容: 我最近遇到了一个令人讨厌的错误,该错误中的代码是通过JavaScript动态加载的。动态加载的具有预先选择的值。在IE6中,我们已经有代码来修复selected ,因为有时的值可能与selected 的属性不同步,如下所示: 但是,此代码无法正常工作。即使正确设置了字段,最终也会选择错误的索引。但是,如果我在正确的时间插入一条语句,则会选择正确的选项。考虑到这可能是某种时序问题,我尝试
本文向大家介绍详解linux ntp服务器时间同步设置,包括了详解linux ntp服务器时间同步设置的使用技巧和注意事项,需要的朋友参考一下 linux ntp服务器时间同步设置 时间同步这个需求在很多地方都有。比如安装cm和cdh的话,需要ntp时间同步,否则会出现红色警告 这里主要是设置一台服务器作为主服务器,让其他机器同步这台机器的时间,而且是配置的本地时间,没有同步internet时间,
本文向大家介绍js设置默认时间跨度过程详解,包括了js设置默认时间跨度过程详解的使用技巧和注意事项,需要的朋友参考一下 有一个项目,需求是进入首页要显示一个月之内的历史记录,所以从前台传到后台的结束时间为当前日期,开始时间为往前一个月。 例如,现在是2018/04/17,则结束时间为2018/04/17,开始时间为2018/03/17. 将开始时间和结束时间传到后台即可。js代码如下: 以上就是本
本文向大家介绍Zabbix指定时间内变化值设置方法详解,包括了Zabbix指定时间内变化值设置方法详解的使用技巧和注意事项,需要的朋友参考一下 背景描述:在现有的一个负载均衡设备上存有某个指标是处于一个增值状态(只会不断增大不会减少,估计是一个计算总量的指标数值),但是总量计算的值参考意义不大,我更需要的是他在指定时间内的变化值。 原监控项,一个持续增量的数据。如图1,图2. 图1 图2
本文向大家介绍iOS中设置网络超时时间+模拟的方法详解,包括了iOS中设置网络超时时间+模拟的方法详解的使用技巧和注意事项,需要的朋友参考一下 设置方法如下: 在封装的网络请求类里面如下设置 AFWEBAPI_REQUEST_TIMEOUT 这个参数为超时时间 在封装的方法里面,在失败的回调里面写下如下代码,至于怎么处置就看自己了,我这里具体需求没有给,我先做了一个弹框处理 如何去调试呢,难道去电