前言
首先要对 setTimeout() 和 setInterval() 有一个概念,学习了 JavaScript 我们知道:setTimeout() 是延时器,setInterval() 是定时器。setTimeout() 在于载入后延迟指定的时间后才会执行一次表达式,执行过后便会停止;setInterval() 在载入后每隔指定时间就会执行一次表达式,直到定时器或者窗口关闭。
对这两者有了初步印象后,我们开始逐个分析
setTimeout()
定义
setTimeout() 方法在指定的毫秒数后调用一次函数或计算表达式。
语法
var timeoutID = setTimeout(code/function, millisec)
参数
- code/funciton:必需。要调用的函数后要执行的 JavaScript 代码串或者函数。
- millisec:必需。在执行代码前需等待的毫秒数。
返回值
返回值 timeoutID 是一个正整数,表示定时器的编号。这个值可以传递给clearTimeout()来取消该定时器。提醒
setTimeout() 只执行 code 一次。如果要多次调用,请使用 setInterval() 或者让 code 自身再次调用 setTimeout()清除 setTimeout()
clearTimeout(timeoutID)
timeoutID 为调用 setTimeout() 函数时所获得的返回值,使用该返回标识符作为参数,可以取消该 setTimeout() 所设定的定时执行操作。统一示例
function eg () { console.log('你好'); } //使用方法名字执行方法 let t1 = window.setTimeout(eg, 1000); //使用字符串执行方法 let t2 = window.setTimeout("eg()", 3000); //清除定时器 window.clearTimeout(t1); window.clearTimeout(t2);
使用场景
- 用于延迟执行某方法或功能
setInterval()
定义
setInterval() 方法重复调用一个函数或执行一个代码段,在每次调用之间具有固定的时间延迟。
语法
语法与 setTimeout() 相同:
var intervalID = setInterval(code/function, delay)
参数
- code/funciton:必需。要调用的函数后要执行的 JavaScript 代码串或者函数。
- millisec:必需。在执行代码前需等待的毫秒数。
返回值
此返回值 intervalID 是一个非零数值,用来标识通过setInterval()创建的计时器,这个值可以用来作为clearInterval()的参数来清除对应的计时器 。提醒
setInterval() 会重复执行多次。如果想只执行一次,请使用 setTimeout()清除 setInterval()
clearInterval(intervalID)
使用场景
- 用于刷新表单,对于一些表单的实时指定时间刷新同步
深入思考
在项目中使用这两者的时候会发现,调用函数的时候时间间隔虽然几乎相同,但并不精确,这时候如果项目中用这两者做动态效果,可能会发现:当程序中同时出现其他各种事件处理程序时,动画会变得不够平滑。那为什么会出现这种情况?
这是由于 JavaScript 其实是运行在单线程环境中的,这就意味着定时器仅仅是计划代码在未来的某个时间执行,而具体执行时机是不能保证的。
打个比方:我设置了一个定时器,这时候这个定时器事件就会被添加到待执行事项中,如果在这个定时器事件之前没有其他事件排队等待执行的话,就可以立即执行定时器事件;但如果前面有很多且耗时很久的事件等待执行,那这个定时器事件就不得不推迟时间执行了,这样一来,就不能如时按照指定的时间运行代码了。
因为这样,才会导致 setTimeout 和 setInterval 执行的时间间隔不能精确。那么有读者可能会问,影响这个时间间隔的因素是什么?答案是运行这两个方法的宿主环境,不同的浏览器、不同系统、不同版本的测试环境都会对其造成影响,事实上 GitHub 上早已有人 issue 该问题,然而至今仍然处于 open 状态:setInterval doesn’t comply with DOM-version、setInterval interval includes duration of callback、setInterval/setTimeout interval should not include duration of callback
后面这个问题如果解决了,笔者会再来更新的~
结语
知道 setTimeout() 和 setInterval() 是怎么一回事之后,在项目中合理采用就好了,一般问题不大,可能面试的时候会问到更加深入的东西?笔者也不知道呢,毕竟暂无面试经历,但准备面试过程中应该也少不了这方面的知识点拓展,有备无患 Orz。
这篇文章有相关的使用案例,可供读者参考:
如果有说得不对的地方,还烦请大佬们指正,笔者愿与大家一起探讨 (^▽^)~~