运行机制
单线程模型
-
setTimeout和setInterval的运行机制是,将指定的代码移出本次执行,等到下一轮Event Loop时,再检查是否到了指定时间。如果到了,就执行对应的代码;如果不到,就等到再下一轮Event Loop时重新判断。这意味着,setTimeout指定的代码,必须等到本次执行的所有代码都执行完,才会执行。
-
setTimeout的作用是将代码推迟到指定时间执行,如果指定时间为0,即setTimeout(f,0),那么不会立刻执行
-
setTimeout(f,0)将第二个参数设为0,作用是让f在现有的任务(脚本的同步任务和“任务队列”中已有的事件)一结束就立刻执行。也就是说,setTimeout(f,0)的作用是,尽可能早地执行指定的任务。
例2
例2:一般以为会理解为一开始isOK为true,一个
while
函数当isOK为true时输出2。一秒钟后setTimeout把isOK设为false,后面就不不执行console.log(2)了。
然而,setTimeout
的异步操作是放在这里面的:
换句话说就是要等所有同步放在stack的代码执行完后,才去看那些异步。然而前面例2里面stack的while无限循环,所以永远看不到后面
setTimeout
。
测试题1:以下代码输出什么
var i=0;
for(var i=0; i<10; i++){
setTimeout(function(){
console.log(i)
}, 1000)
}
// for循环是同步的代码先去执行,等for循环执行完毕时,i此时变为10,才去执行后面代码,相当于后面创建了是个定时器都是1秒后执行,所以是10个10.
image.png
测试题2:以下代码输出什么
var t = true;
setTimeout(function(){
t = false;
}, 1000);
while(t){ }
console.log('end')
// 道理类似前面,前面卡住,setTimeout里面代码永远不会执行。
异步与回调
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()
image.png
执行f1,f1里面执行完之后,把f1里面的参数按函数执行。场景:f1执行完毕后得到数据,结果ok之后交给f2输出。
改造后:
image.png
f1执行完成后,执行里面的callback的函数,而callback的里面的i作为函数的参数。
回调后面还有
promise
函数节流
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()
fn2()
fn2()
在一定时间内连续执行代码,以最后一次为准。
网友评论