3.4定时器
3.4 定时器
1. JS存在两种定时器:
setTimeout 延迟定时器(回调函数执行一次)
setInterval 循环定时器(回调函数执行无数次)
2.定时器中的函数挂载在window对象,内部的this ----> window
3.定时器的用法:setInterval/setTimeout(参数,1000) 1000毫秒==1秒
4.如果一个函数当做实参,则这个函数叫做回调函数,定时器就是回调函数
setTimeout(function(形参1,形参2,形参n){
console.log(1)
},1000,实参1,实参2,实参n)
setTimeout()的第一个参数是回调函数,第二个参数是毫秒数,第三个参数是给回调函数的形参
5.回调函数的写法:匿名函数(常用形式),字符串,函数名
例1:函数名
setInterval(auto,1000,'我是回调函数执行时传递的实参',2)
function auto(a,b){
console.log(a,b); // a:我是回调函数...实参, b:2
}
例2:字符串:setTimeout('console.log([1,22])',1000)
6.清除定时器 在每次使用定时器时,都需要清除
clearInterval() 清除循环定时器
clearTimeout() 清除延迟定时器
写法:
①clearInterval(第几个定时器)
②把回调函数赋值给一个变量,执行clearInterval(变量)就可以中止该定时器
注:两种定时器分别要用专门的清除定时器去清除,clearTimeout()都可以清除
setInterval(function(){
console.log(1)
},1000)
setInterval(function(){
console.log(10)
},500)
setInterval(function(a,b){
console.log(a,b)
},1000,123123,"按数据库和迪奥的")
clearTimeout(1) //清除第一个定时器

7.定时器的返回值
表示在JS代码中出现的第几个定时器
var timer1 = setInterval(function(){
//console.log('timer1执行');
},200);
var timer2 = setTimeout(function(){
//console.log('timer2执行');
},300)
var timer3 = setTimeout(function(){
//console.log('timer2执行');
},100)
console.log(timer1); //返回1,表示第一个定时器
console.log(timer2); //返回2,表示第二个定时器
console.log(timer3); //返回3,表示第三个定时器

8.单线程,同步任务/异步任务
单线程:同时只能执行一个任务,如果后面有任务,需要等到当前任务执行完毕,才能执行后面的任务
JS任务分类:同步任务,放置在主线程中执行
异步任务:放置在异步队列中等待
(异步任务有定时器的回调函数,点击事件,Ajax)
处理任务的顺序:先做完同步任务,再做任务异步任务,在多个异步任务中,再分别看异步任务的时间
真正的异步是回调函数的异步,时间是同步的,就只有定时器的第一个值是异步
例1:
var oBox = document.getElementById('box');
var a = 2;
var b = 3;
var c = 4;
console.log(c);
setTimeout(function(){
console.log('heaven');
},100);
setTimeout(function(){
console.log(b);
},0);
console.log(a);
oBox.onclick = function(){
console.log('我被点击了');
}
onclick是异步任务,是被点击的时候才执行,所以是在最后
//打印结果 先执行同步,后执行异步 4-->2-->3-->'heaven'-->'我被点击了'

9.线程阻塞
前面的任务死循环或者耗时过长导致后面代码不能被执行,这种情况叫做线程阻塞
例1:
for(var i=0;i<100000;i++){
console.log(1);
}
setTimeout(function(){
console.log(2);
},10)

例2:
for(var i=0;i<5;i++){
/*
* i=0 向异步队列中放一个异步任务
* i=1 向异步队列中放一个异步任务
* i=2 向异步队列中放一个异步任务
* i=3 向异步队列中放一个异步任务
* i=4 向异步队列中放一个异步任务
* i=5 执行异步队列的任务
* */
setTimeout(function(){
console.log(i)
},i*1000)
}

真正的异步是回调函数的异步(黄色代码),就只有定时器的第一个值是异步,i*1000同步的,所以每次执行for循环就打印一次,如果不写i,就直接打印5个5
闭包的写法,为了每次获得0-4的值
for(var i=0;i<5;i++){
/*
* i=0 向异步队列中放一个异步任务
* i=1 向异步队列中放一个异步任务
* i=2 向异步队列中放一个异步任务
* i=3 向异步队列中放一个异步任务
* i=4 向异步队列中放一个异步任务
* i=5 执行异步队列的任务
*/
(function(i){ //自执行函数
//AO{i:0}
//AO{i:1}
//AO{i:2}
setTimeout(function(){ //延长了函数的作用域,找到父级的AO
//i=0 AO{i:0}+GO
//i=1 AO{i:1}+GO
//i=2 AO{i:2}+GO
console.log(i);
},1000)
})(i)
}

i=0,开始自执行函数,函数AO中i=0, 执行异步序列,此时i顺着作用域链查找。


浙公网安备 33010602011771号