setInterval 模拟 setTimeout
function mySetTimeout(fn, time) {
let timer = null
function timeout() {
fn()
clearInterval(timer)
}
timer = setInterval(timeout, time)
return {
cancel: () => clearInterval(timer)
}
}
var result = mySetTimeout(() => {
console.log('mySetTimeout')
}, 3000)
setTimeout(() => {
result.cancel()
// console.log('提前执行了清空')
console.log('延后执行了清空')
}, 4000)
setTimeout 模拟 setInterval
function myInterval(fn, time) {
let timer = null, isClear = false;
function interval() {
if (isClear) {
isClear = false
clearTimeout(timer)
return
}
fn()
timer = setTimeout(interval, time)
// console.log('timer - 1', timer)
}
timer = setTimeout(interval, time)
// console.log('timer - 2', timer)
// 返回一个清空定时器方法
return {
cancel: () => isClear = true
}
}
let count = 0;
let result = myInterval(() => {
count++
console.log('1 - myInterval', count)
if (count === 3) {
result.cancel()
}
}, 3000)
思路:
- 两个变量
timer
和clear
来存放当前定时器 ID,和清空定时器开关; - 声明
interval
函数(重点),用来模拟setInterval
; - 触发
interval
函数执行,需要setTimeout
。 - 返回清空定时器方法:
cancel
;
注意:**timer**
值是一直变的,需要取到最后一个**timer**
值,用来清空最后一个定时器。
// 法二:
function myInterval(fn, time) {
let timer = null;
function interval() {
timer = setTimeout(interval, time)
fn(timer)
// console.log('timer - 1', timer)
}
timer = setTimeout(interval, time)
// console.log('timer - 2', timer)
return {
cancel: (t) => clearTimeout(t)
}
}
let count = 0;
let result = myInterval((timer) => {
count++
// console.log('timer - 3', timer)
if (count === 3) {
result.cancel(timer)
}
}, 3000)
requestAnimationFrame 模拟 setInterval
function setInterval(callback, interval) {
let timer
const now = Date.now
let startTime = now()
let endTime = startTime
const loop = () => {
timer = window.requestAnimationFrame(loop)
endTime = now()
if (endTime - startTime >= interval) {
startTime = endTime = now()
callback(timer)
}
}
timer = window.requestAnimationFrame(loop)
return timer
}
let a = 0
setInterval(timer => {
console.log(1)
a++
if (a === 3) cancelAnimationFrame(timer)
}, 1000)