定时器
JavaScript提供定时执行代码的功能,叫做
定时器(timer)
,主要由setTimeout()
和setInterval()
这两个函数来完成。
setTimeout()
setTimeout函数
用来指定某个函数或某段代码,在多少毫秒之后执行。它返回一个整数,表示定时器的编号,以后可以用来取消这个定时器。
-
delay
是推迟执行的毫秒数,默认为0 - 异步的过程
- 间隔只执行一次
var timeoutId = setTimeout(func,delay)
clearTimeout(timeoutId) 清除定时器
setInterval()
-
func
执行改变属性的操作 -
delay
触发的时间间隔 - 一直执行
var intervalId = setInterval(func,delay)
clearInterval(intervalId) 清除定时器
requestAnimationFrame
- 浏览器自己控制频率
- 用户不用关心间隔时间
- 动画更流畅
var requestId = requestAnimationFrame(func)
cancelAnimationFrame(requestId)
clearTimeout()取消定时器
clearInterval()取消定时器
cancelAnimationFrame
运行机制
setTimeout和setInterval
的运行机制是,将指定的代码移出本次执行
,等到下一轮Event Loop时,再检查是否到了指定时间
。如果到了,就执行对应的代码;如果不到,就等到再下一轮Event Loop时重新判断。这意味着,setTimeout指定的代码,必须等到本次执行的所有代码都执行完,才会执行。
单线程模型
setTimeout
的作用是将代码推迟到指定时间执行,如果指定时间为0,即setTimeout(f,0)
,那么不会立刻执行setTimeout(f,0)
将第二个参数设为0,作用是让f在现有的任务(脚本的同步任务和“任务队列”中已有的事件)一结束就立刻执行。也就是说,setTimeout(f,0)的作用是,尽可能早地执行指定的任务。
console.log(1);
setTimeout('console.log(2)',1000);
console.log(3);
// 1
// 3
// 2
依次输出1,3,2,因为setTimeout是异步的,所以浏览器会吧代码放在callbackqueue中,
等待stack中的任务运行完,在运行,所以结果是这个
for(var i=0; i<10; i++){
setTimeout(function(){
console.log(i)
}, 1000)
}
//结果是10个10
for循环完成i变为10,过了一秒以后才执行定时器,相当于创建了10个定时器
var t = true;
setTimeout(function(){
t = false;
}, 1000);
while(t){ }
console.log('end')
//结果是无限循环
因为setTimeout会被放在任务队列中,然后执行while,因为t= true,
所以一直执行while(t){}
异步和回调
function f1(callback){
setTimeout(function(){
//做某件事,可能很久
console.log('别急,开始执行f1')
for(var i=0;i< 100000;i++){
}
console.log('f1执行完了')
callback() // 回调函数
}, 0);
}
function f2(){
console.log('执行f2');
}
function f3(){
console.log('执行f3');
}
f1(f2) //当f1执行完之后再执行 f2
f3()
函数节流
用户执行一个事件过多次,我们只取最后一次的结果
var timer //开始是undefined
function hiFrequency(){ //hiFrequency用户快速执行的事件
if(timer){
clearTimeout(timer) //开始是不执行的
}
timer = setTimeout(function(){
console.log('do something')
}, 300) //在300ms后执行,如果在300ms以内再次执行hiFrequency,clear
}
hiFrequency()
hiFrequency()
hiFrequency() //do somthing 只执行最后一次
封装成函数
function throttle(fn, delay) {
var timer = null
return function(){
clearTimeout(timer)
timer = setTimeout(function(){
fn(arguments)
}, delay)
}
}
function fn(){
console.log('hello ')
}
var fn2 = throttle(fn, 1000)
fn2()
fn2()
fn2()
网友评论