一:setTimeout(): 用于指定在一定时间后执行某些代码
1、接受两个参数要
执行的代码
+执行回调函数前等待的时间(毫秒)
** 第二个参数指的是要等待的毫秒数,而不是执行代码的确切时间
2、JavaScript是单线程,所以每次只能执行一段代码。为了调度不同代码的执行,JavaScript维护了一个任务队列。其中的任务会按照添加到任务队列的先后顺序执行
**setTimeout()中的第二个参数只是告诉JavaScript引擎在指定的毫秒数过后把任务队列添加到这个队列。如果队列是空的,则会立即执行。如果队列不是空的则代码必须等待前面的任务执行完才能执行
3、调用setTimeout()时,会返回一个表示该超时排期的数值ID
,ID是被排期执行代码的唯一标识符
**clearTimeout(数值ID) //取消超时任务
let timeoutId = setTimeout(()=>{
console.log('执行方法体')
},500)
clearTimeout(timeoutId) //取消超时任务
clearTimeout()只是在指定时间达到之前调用,可以取消超时任务。在执行任务后再屌用则没有效果。 (因为它会在条件满足执行完自动结束)
二:setInterval(): 用于指定每隔一段时间执行某些代码
1、接受两个参数要
执行的代码
+执行回调函数前等待的时间(毫秒)
(同setTimeout)
** 第二个参数指的是要等待的毫秒数,而不是执行代码的确切时间
2、第二个参数指的是间隔时间,指的是向队列添加新任务之前等待的时间。
例如:调用setInterval()任务的时间为01:00:00,间隔时间为3000毫秒。这就意味着01:00:03时,浏览器会把任务添加到任务队列。浏览器并不关心这个任务什么时候执行或者执行需要花多少时间。因此,到了01:00:06,它会向队列中添加一个任务。由此可看,执行时间短、非阻塞的回调函数比较适合setInterval()
3、调用setInterval()时,会返回一个循环定时ID
,可用于在未来某个时间点上取消循环定时
**clearInterval(定时ID) //取消定时任务,如果不取消,那么定时任务会一直执行到页面卸载
setInterval()很少会在生产环境下使用,因为一个任务结束和下一个任务开始之间的时间间隔是无法保证的,有些循环定时任务可能会因此而跳过
1、setInterval()可能会导致的问题
1、前一任务结束到当前任务开始的时间间隔与设置的delay值不符。
2、可能出现某些任务被跳过的情况
1.1假如定时器里面的代码需要进行大量的计算(耗费时间较长)或者 DOM 操作。这样一来,花的时间就比较长,有可能前一次代码还没有执行完,后一次代码就被添加到[队列]了。也会使定时器变得不准确。
setInterval(fun, delay)
//当fun执行消耗400ms,delay为300ms时,前一个任务执行结束到后一个任务开始执行间隔为-100ms
1.2假设setInterval 每隔 400ms 往队列中添加一个事件;400ms 后,添加 T1 定时器代码至队列中,主线程中还有任务在执行,所以等待。some event 执行结束后执行 T1 定时器代码;又过了 400ms,T2 定时器被添加到队列中,主线程还在执行 T1 代码,所以等待;又过了 400ms,理论上又要往队列里推一个定时器代码,但由于此时 T2 还在队列中,所以 T3 不会被添加(T3 被跳过),结果就是此时被跳过;这里我们可以看到,T1 定时器执行结束后马上执行了 T2 代码,所以并没有达到定时器的效果
三:两种方法代码实现对比,更推荐使用setTimeout()
setInterval()
let num = 0;
let intervalId = null;
let max = 10;
let increamNumber = function(){
num++;
if(num == max) {
clearInterval(intervalId);
alert('Done')
}
}
intervalId = setInterval(increamNumber, 500)
setTimeout()
也可以用setTimeout()实现,且更推荐使用它
let num = 0;
let max = 10;
let increamNumber = function(){
num++;
if(num == max) {
setTimeout(increamNumber, 500) //方法执行完以后作为开始点再设置间隔时间等待
} else {
alert("Done")
}
}
setTimeout(increamNumber, 500)