setTimeout() 与 setInterval() 的区别

2,576 阅读4分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第2天,点击查看活动详情

前言

首先我们要对 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-versionsetInterval interval includes duration of callbacksetInterval/setTimeout interval should not include duration of callback

结语

知道 setTimeout() 和 setInterval() 是怎么一回事之后,在项目中合理采用就好了,一般问题不大,可能面试的时候会问到更加深入的东西?笔者也不知道呢,毕竟暂无面试经历,但准备面试过程中应该也少不了这方面的知识点拓展,有备无患 Orz。

这篇文章有相关的使用案例,可供读者参考:

setTimeout和setInterval的区别以及如何写出效率高的倒计时

如果有说得不对的地方,还烦请大佬们指正,笔者愿与大家一起探讨 (^▽^)~~