Skip to main content

2 posts tagged with "setTimeout"

View All Tags

· 5 min read
Robbie Han

setTimeout 和 setInterval 功能

setTimeout()会在确定的时间调用回调函数,且回调函数只会执行一次。

setInterval()会重复调用一个函数,在每次调用之间具有固定的时间延迟。

为什么要模拟

为什么使用setTimeout模仿setInterval呢?这需要通过事件循环机制来解释,如果不清楚的话可以点击查看事件循环机制浏览器内核相关内容。

由于setIntervalsetTimeout不是 JS 中定义的,他们并不会在 JS 引擎线程中直接执行。当代码执行到setIntervalsetTimeout时,事件循环机制会为setTimeoutsetInterval开一个定时器线程并开始计时,等定义的时间过后,将回调函数放到回调队列里,等到函数调用栈空(JS引擎线程空闲)时,将回调函数放入函数调用栈(使用 JS 引擎线程)执行。

· 4 min read
Robbie Han

前言:

浏览器事件循环经典题目:

for (var i=0; i<5; i++) {
setTimeout( function timer() {
console.log(new Date, i);
}, 1000);
}
VM84:3 Wed Oct 09 2019 09:29:47 GMT+0800 (中国标准时间) 5
VM84:3 Wed Oct 09 2019 09:29:47 GMT+0800 (中国标准时间) 5
VM84:3 Wed Oct 09 2019 09:29:47 GMT+0800 (中国标准时间) 5
VM84:3 Wed Oct 09 2019 09:29:47 GMT+0800 (中国标准时间) 5
VM84:3 Wed Oct 09 2019 09:29:47 GMT+0800 (中国标准时间) 5

解析: 根据 setTimeout 定义的操作在函数调用栈清空之后才会执行的特点,for 循环里定义了 5 个 setTimeout 操作。而等待 1 秒后,任务队列里的 setTimeout 开始依次执行时,for 循环的 i 值,已经先一步变成了 5。因为任务队列推到函数调用栈执行的时间可以忽略不记(毫秒级),所以打印的 GMT 时间(精确到秒)和 i 的值都是相同的。