快捷搜索:  汽车  科技

setinterval功能:一文搞懂setTimeout和setInterval区别

setinterval功能:一文搞懂setTimeout和setInterval区别这里可能会存在两个问题:1.时间间隔或许会跳过2.时间间隔可能小于定时调用的代码的执行时间setInterval可以当成setTimeout的升级版,就像setTimeout循环调用自身,用法也跟setTimeout一样,用完时也要记得用clearInterval清掉定时器。funcName:function() {   // dosomething1 setTimeout(() => { // dosomething2 } 500);   // dosomething3 }以上代码的执行顺序是:先执行dosomething1的内容 然后运行到setTimeout的地方 setTimeout会告诉浏览器说: "500ms后会插一段要执行的代码给你的队列中" 浏览器答应了(注意插入代码并不意味着立马执行) setTimeout代码运

setinterval功能:一文搞懂setTimeout和setInterval区别(1)

最近在开发小程序中,经常用到setTimeout和setInterval函数,曾经经常搞混这两个函数的使用,特意研究了一下这里做下总结,希望同行看了能有所收获,不再迷路。

首先,要说明的是setTimeout和setInterval是两个实现了定时调用的函数,而不是类似thread的线程。线程一般会在一个时间片内 可以并发的执行调用 但这两个函数并不是这样使用的,因为我们都知道JavaScript都是以单线程的方式运行于浏览器的JavaScript引擎中的。

setTimeout和setInterval的作用只是把你要执行的代码在你设定的一个时间点插入JavaScript引擎维护的一个代码队列中 插入代码队列并不意味着你的代码就会立马执行的,理解这一点很重要。

一、setTimeout

setTimeout() 只执行 code 一次。如果要多次调用,请使用 setInterval() 或者让 code 自身再次调用 setTimeout()。

funcName:function() {   // dosomething1 setTimeout(() => { // dosomething2 } 500);   // dosomething3 }

以上代码的执行顺序是:先执行dosomething1的内容 然后运行到setTimeout的地方 setTimeout会告诉浏览器说: "500ms后会插一段要执行的代码给你的队列中" 浏览器答应了(注意插入代码并不意味着立马执行) setTimeout代码运行后 紧跟其后的dosomething3代码开始执行。

问题来了,如果dosomething3的代码执行时间超过500ms 那结果会是如何? 500ms一到 dosomething2代码会立马执行吗?事实可能会让你有点失望 在dosomething3执行过程中(执行了500ms后)dosomething2代码被插入代码队列 但一直要等funcName的方法执行结束 才会执行dosomething2代码段 从代码队列上看dosomething2代码是在funcName后面的 再加上js以单线程方式执行 所以就很容易理解了。 如果是另一种情况 dosomething3代码执行的时间<500ms setTimeout在500ms后将dosomething3代码插入到代码队列 而那时执行线程可能已经处于空闲状态了 那结果500ms后 dosomething2代码插入队列就立马执行了 然后你感觉500ms后 就立即执行了。

用完定时器之后,要记得清除:clearTimeout(timeoutId) 这里的timeoutId是setTimeout返回的一个正整数编号,是定时器的唯一标识符。

setinterval功能:一文搞懂setTimeout和setInterval区别(2)

二、setInterval

setInterval可以当成setTimeout的升级版,就像setTimeout循环调用自身,用法也跟setTimeout一样,用完时也要记得用clearInterval清掉定时器。

这里可能会存在两个问题:
1.时间间隔或许会跳过
2.时间间隔可能小于定时调用的代码的执行时间

click:function() {   // dosomething1 setInterval(() => { // dosomething2 } 500);   // dosomething3 }

同样当funcName开始执行时,当dosomething1代码执行完后执行setInterval 以此为一个时间点 在200ms后插入dosomething2代码 funcName代码顺利结束 dosomething2代码开始执行 如果dosomething2代码也执行了一个比较长的时间 超过了接下来一个插入时间点400ms 这样代码队列后又插入了一份dosomething2代码 dosomething2继续执行着 而且超过了600ms这个插入时间点 然后问题就来了 开始以为代码队列后面会继续插入一份dosomething2代码...而实际情况是 由于代码队列中已经有了一份未执行的dosomething2代码 所以600ms这个插入时间点将会被"无情"的跳过 因为JavaScript引擎只允许有一份未执行的dosomething2代码,惊不惊喜意不意外?

所以有一种更好的方式来实现此功能,主要思路是递归:

setTimeout(() => { //processing setTimeout(arguments.callee interval); } interval);

这里有个知识点:

arguments 的主要用途是保存函数参数, 有个callee属性,返回正被执行的Function对象,也就是所指定的Function对象的正文,这有利于匿名函数的递归或者保证函数的封装性。

但是现在已经不推荐使用arguments.callee();

因为访问 arguments 是个很昂贵的操作,因为它是个很大的对象,每次递归调用时都需要重新创建,影响现代浏览器的性能,还会影响闭包。

三、setTimeout和setInterval区别

setInterval在执行完一次代码之后,经过了给定的时间间隔,它还会自动重复执行代码,而setTimeout只执行一次那段代码。

setInterval和setTimeout都返回定时器对象标识符,用于clearInterval和clearTimeout调用

clearTimeout(showTimes) //清除已设置的setTimeout对象 clearInterval(showTimes) //清除已设置的setInterval对象

  • setTimeout用于延迟执行某方法或功能
  • setInterval则一般用于刷新表单,对于一些表单的假实时指定时间刷新同步

现在是不是觉得很简单,很容易区分?那么下面两个例子就很容易区分差别了。

例一:

setTimeout(function(){ console.log("小马"); setTimeout(function(){arguments.callee;} 1000); } 1000)

例二:

setInterval(function(){ console.log("小马"); } 1000);

猜您喜欢: