一、我们可以设置一个定时器用以指定某个程序在指定时间后才执行
1 setTimeout(function(){ 2 console.log("do something"); 3 },1000)
用setTimeout,指定1秒后执行
二、当然也可以在想要清除定时器的时候,想办法清除它
只需要给setTimeout起一个别名,clearTimeout这个别名即可
1 // 给定时器起个别名st1 2 var st1 = setTimeout(function(){ 3 console.log("do something"); 4 },1000) 5 6 7 // 清除定时器st1 8 clearTimeout(st1)
别名st1的值为该setTimeout的返回值,该返回值是timeoutID ,是一个正整数,从数字1开始命名,多个定时器其它返回值是从1开始依次编号,即1 2 3 4,表示定时器的编号,这个值可以传递给clearTimeout()来取消该定时器
三、如果你想在指定这个定时器时传递一些参数也是可以的
值得一提的是setTimeout可以传多个参数
setTimeout(function(){}, 时间,参数1,参数2,参数3 ...)
1 var p1 = '参数1', p2 = '参数2', p3 = '参数3'; 2 3 var st1 = setTimeout(function(p1, p2, p3){ 4 console.log("do something 传递的参数:", p1, p2, p3); 5 },1000, p1, p2, p3) 6 7 // 或者 8 var st1 = setTimeout(function(a, b, c){ 9 console.log("do something 传递的参数:", a, b, c); 10 },1000, '参数1', '参数2', '参数3')
四、定义多个定时器,且将其赋值给
1 var st1 = setTimeout(function(i){ 2 console.log(i); 3 },1000,11) 4 5 var st2 = setTimeout(function(i){ 6 console.log(i); 7 clearTimeout(st3); 8 },2000,22) 9 10 var st3 = setTimeout(function(i){ 11 console.log(i); 12 },3000,33)
执行结果是:
11
22
因为在第7行,清除了定时器st3,因此st3不存在了
五、将setTimeout放在循环中会怎么样
1 function fn(){ 2 for(var i=0; i<3; i++){ 3 var st1 = setTimeout(function(i){ 4 console.log('x', i); 5 clearTimeout(st1); 6 },1,i) 7 console.log('y', i); 8 } 9 } 10 fn();
执行结果是:
y 0
y 1
y 2
x 0
x 1
分析
这里用到了Event Loop即事件循环知识,
一段代码,首先要区分是“同步任务”还是“异步任务”,“同步任务”总是早于“异步任务”先顺序执行,
for循环内,只有两大块代码,
分别是:
属于“同步任务”的var定义(但var定义等号右边setTimeout是个“异步任务”)
属于“同步任务”的 console.log('y', i);
具体执行是这样的:
i=0时,遇到var定义,执行var 赋值操作,将st1值赋值为定义setTimeout时的返回值 即 1,但考虑到setTimeout是“异步任务”且细说属于“宏任务”,遂将其添加到“任务队列”的“宏任务”子队列中
这时我们看变量st1的值是第一个setTimeout时定义返回值即这个定时器编号数字1
遇到console.log('y', i); 输出 y 0
i=1时,遇到var定义,执行var 赋值操作,将st1值赋值为定义setTimeout时的返回值 即 2,但考虑到setTimeout是“异步任务”且细说属于“宏任务”,遂将其添加到“任务队列”的“宏任务”子队列中
这时我们看变量st1的值是第二个setTimeout时定义返回值即这个定时器编号数字2
遇到console.log('y', i); 输出 y 1
i=2时,遇到var定义,执行var 赋值操作,将st1值赋值为定义setTimeout时的返回值 即 3,但考虑到setTimeout是“异步任务”且细说属于“宏任务”,遂将其添加到“任务队列”的“宏任务”子队列中
这时我们看变量st1的值是第三个setTimeout时定义返回值即这个定时器编号数字3
遇到console.log('y', i); 输出 y 2
“执行栈”中,“同步任务”代码执行完了,这时就去从“任务队列”中去按“先入先执行”的原则顺序,依次载入“执行栈”,挨个执行,值得一提的是从“任务队列”中调用任务总是先看是否有“微任务”,如果有,则,从“微任务”中,依次载入“执行栈”执行,“微任务”为空,则从“宏任务”调入执行
这里,
1.首先将“编号1的setTimeout”载入“执行栈”执行,输出 x 0 ,其中 clearTimeout(st1),由于此时 st1为“第三个setTimeout时定义返回值即这个定时器编号数字3”,所以,将执行清除“编号3的定时器”动作
2.将“编号2的setTimeout”载入执行栈执行,输出 x 1,再次 clearTimeout(st1) 清除“编号3的定时器”动作
3.由于“宏任务”中“编号3的setTimeout”被清除,因此,“宏任务”被全部执行完毕,程序也到此为止