-
简单提一下用法
setTimeout(fn,delay,[, args...] ) setInterval(fn,delay,[, args...] )
-
相同点
-
均为宏任务,计时结束后,在js主线程排队等待执行。例如设置delay 延时为1000。那执行的延迟肯定会大于(取决于主线程是否有正在执行的)或等于1s
-
若主线程在它们前面执行的任务,发生了阻塞(例如死循环等)变不会执行回调。例如
var t = true; setTimeout(function(){ t = false; }, 1000); while(t){ } alert('end'); // end 不会弹出
- 不同点
-
setTimeout 为延时执行。setInterval为设定间隔时间循环执行
-
setInterval每执行一次都会进入主线程的任务队列中‘排队’执行。若进入任务队列中存在‘同样的任务(即前面进入队列排队的任务还没有执行)’则当前任务会被忽略掉不进入任务队列等待执行。
-
setInterval 如果参数中的fn 执行时间过长,则可能会出现没有时间间隔循环执行的效果。可以理解为(setInterval则总是在每10ms的时候尝试执行一次回调,它不管上一次回调是什么时候执行的。)
-
代码实践示例:返回倒计时函数
/**
- 倒计时器
- @param {Number} total 倒计时总数(秒)
- @param {Function} callback 回调函数
- @return {Function} stop 返回结束函数
*/function countDown(total, callback) {
var startTime = new Date().getTime();
var count = 0
let timer = null
function fixed() { //这里做 时间修正 count++;
var offset = new Date().getTime() - (startTime + count * 1000)
var nextTime = 1000 - offset
if (nextTime < 0) nextTime = 0
timer = setTimeout(fixed, nextTime)
callback(total--)
}
timer = setTimeout(fixed, 1000)
return function () {
clearTimeout(timer)
} }
-
总结:
- 无论是setTimeout还是setInterval,触发时,如果当前进程不为空,都得去排队等待执行,这一点上是无差异的。
- 区别是,setTimeout只需排一次队,setInterval则需要按照预设的间隔时间,每到时间点都去排一下。
- setInterval去排队时,如果发现自己还在队列中未执行,则会被drop掉。也就是说,同一个inerval,在队列里只会有一个。
- 因为队列机制,无论是setTimeout还是setInterval,第一次触发时的时间,只会等于大于预设时间,不可能小于。
- 对于setInterval来说,如果执行时间大于预设间隔时间,很可能导致连续执行,中间没有时间间隔,这是很糟糕的,很可能会耗费大量cpu.
引用:www.cnblogs.com/youxin/p/33…
www.cnblogs.com/crith/p/996…