setTimeout用法 & 任务队列异步函数节流
定时器
setTimeOut
setTimeout函数用来指定某个函数或某段代码
在多少毫秒之后执行。
function f(){
console.log(2);
}
setTimeout(f,1000);
// 或者
setTimeout(function (){console.log(2)},1000);
在1000ms后执行这个定时器
他的返回值可以认为是一个定时值的id
可以通过clearTimeOut取消定时器
SetIntervial
可以不间断的进行定时器
- 展示日期
var i =1
var time = setInterval(function(){
console.log(new Date())
},1000)
###单线程模式
- 代码放在Stack当中
var isOk = true
setTimeout(function(){
console.log(1)
isOk = false
}, 1000)
while(isOk){
console.log(2)
}
var i=0;
for(var i=0; i<10; i++){
setTimeout(function(){
console.log(i)
}, 1000)
}
输出10个十
先执行完成for循环里面的for ,使得叠加到了10的程度。这时候再去执行定时器的内容,等同于创建了10个定时器,在1s后执行
- serTimeOut并不只是执行时间的看法,也不是只设为零就是零,设为1就是1
任务队列异步与回调
异步与回调
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
function hiFrequency(){
if(timer){
clearTimeout(timer)
}
timer = setTimeout(function(){
console.log('do something')
}, 300)
}
hiFrequency()
hiFrequency()
hiFrequency()
函数节流改造
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()
下面这段代码输出结果是? 为什么?
var a = 1;
setTimeout(function(){
a = 2;
console.log(a);
}, 0);
var a ;
console.log(a);
a = 3;
console.log(a);
1,3,2
setTimeout会被放到任务队列中,在现有的任务(脚本的同步任务和任务队列中已有的事件执行完成后再执行)
实现一个节流函数。
var timer
function hifrequence() {
if(timer) {
clearTimeout(timer)
}
timer = setTimeout(function(){
console.log('continue do something')
},1000)
}
hiFrequence()
hiFrequence()
简单解释单线程、任务队列的概念。
单线程
- 单线程模型指的是,JavaScript只在一个线程上运行。也就是说,JavaScript同时只能执行一个任务,其他任务都必须在后面排队等待。
- JavaScript只在一个线程上运行,不代表JavaScript引擎只有一个线程。事实上,JavaScript引擎有多个线程,单个脚本只能在一个线程上运行,其他线程都是在后台配合。
任务队列
- 里面是各种需要当前程序处理的消息。新的消息进入队列的时候,会自动排在队列的尾端。
- 运行线程只要发现消息队列不为空,就会取出排在第一位的那个消息,执行它对应的回调函数。等到执行完,再取出排在第二位的消息,不断循环,直到消息队列变空为止。
- 另一种情况是setTimeout会在指定时间向消息队列添加一条消息。如果消息队列之中,此时没有其他消息,这条消息会立即得到处理;否则,这条消息会不得不等到其他消息处理完,才会得到处理。因此,setTimeout指定的执行时间,只是一个最早可能发生的时间,并不能保证一定会在那个时间发生。