• setTimeout的那些事


     

    一、我们可以设置一个定时器用以指定某个程序在指定时间后才执行

    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”被清除,因此,“宏任务”被全部执行完毕,程序也到此为止 

  • 相关阅读:
    js ++i和i++的区别
    js斐波那契数列
    js二分查找算法
    js查找、自组织数据
    查找数组最小值、最大值
    CSS布局(圣杯、双飞翼、flex)
    碰撞检测实现
    ECharts注释
    购物查看放大
    动手封装一个滚轮事件吧!
  • 原文地址:https://www.cnblogs.com/rapale/p/14979043.html
Copyright © 2020-2023  润新知