最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 「查漏补缺」定时器与手写防抖debounce

    正文概述 掘金(SwordQiu)   2020-12-16   638

    之前写异步JS时不小心把定时器给遗漏了,作为异步函数,有时候我们优化性能,减轻页面压力需要用到定时器,然后在查阅文档时也发现了自己的一些不足,于是尽量在这篇文章上补齐,方便自己以后能回顾。

    setTimeout()

    当delay秒之后执行function函数

    参数

    • function 当定时器结束,会自动执行这个函数
    • code 可以使用字符串代替函数(不推荐这种语法)
    • delay 延时(单位:毫秒),如果这个参数是0,可以省略
    • args 参数,这个参数会传递给function

    示例:

    setTimeout((...args)=>{
       console.log(args)
    },1000,1,2,3,4,5)
    // 1秒钟后结果:[1,2,3,4,5]
    
    // 不建议的操作
    setTimeout('console.log(123)',1000)  //现在谷歌已经拒绝这样的用法了
    

    setTimeout()执行后会返回一个id,这个结果是定时器的编号,通过这个编号我们可以取消定时器

    let timer=setTimeout(()=>{console.log(123)})
    clearTimeout(timer)
    

    定时器与this

    需要注意的是定时器会将函数内部的运行环境设置为全局运行环境,也就是指向window

    var x= 1
    var obj={
       x:2,
       y(){console.log(this.x)}
    }
    setTimeout(obj.y,1000) //2
    

    在obj.y当成参数时,会隐式丢失函数内部的this,所以上面的打印结果为2

    解决方法:

    1、传递一个函数,让obj.y在函数内部执行

    setTimeout(()=>{obj.y()},1000)
    

    2、使用bind绑定

    setTimeout(obj.y.bind(obj),1000)
    

    setInterval()

    这个函数跟setTimeout的用法基本一样,只不过它是隔一段时间执行,就相当于每隔一个delay执行function。

    注意:这个函数是多少秒之后开始执行,它不会管执行的时间。假设一个任务是定时100ms执行一个函数,而这个函数执行需要花费5ms,那么第一次之后定时器都会在任务执行后的95ms后执行,所以时间方便不会很精确。

    所以一般我们使用setTimeout来模拟setInterval

    var timer=null
    let count =0
    function fn(){
       clearTimeout(timer)
       timer = setTimeout(()=>{
          count +=1  
          console.log(count)
          fn()
       },1000)
       if(count ===10){
         clearTimeout(timer)}
    }
    

    上面这段代码我尽可能想每一次都清除前一个定时器,目前代码运行没问题,如果您有更好的想法,请贴到下方评论区。

    防抖

    看了网上很多人的防抖代码,一上来就贴全部代码,实在看不懂,我在理解了防抖概念后,写了一个简单版防抖并做了封装。如果您有更好的想法和思路,请贴到下方评论区教教我。

    先说下我的思路:

    我目前对防抖的概念就是使用清除定时器来对用户的操作进行限制,相当于一个cd条,如果打断了,就不执行(清除定时器)。

    比如我现在要做一个button按钮,点击两秒钟后打出一句123,说干就干。

    let btn=document.querySelector('button')
    btn.addEventListener('click',()=>{
      setTimeout(()=>{console.log(123)},1000)
    })
    

    没有防抖前效果如下 「查漏补缺」定时器与手写防抖debounce 简单做个防抖

    let btn=document.querySelector('button')
    let timer=null
    btn.addEventListener('click',()=>{
      clearTimeout(timer) //每点一次都清除上一次的timer,上一次的就不会执行
      timer=setTimeout(()=>{console.log(123)},1000)
      console.log(timer)
      //这句代码是为了证明获取timer比console早
      //只要执行了setTimeout就拿到timer了,不用执行参数函数console
    })
    

    效果如下: 「查漏补缺」定时器与手写防抖debounce

    优化代码

    let btn=document.querySelector('button')
    
    function debounce(handler,delay){//delay就是1000ms
       let timer=null
       return function (){
          clearTimeout(timer)
          timer=setTimeout(handler,delay)
       }
    }
    const handler=()=>{console.log(123)} 
    btn.addEventListener('click',debounce(handler,1000))
    

    优化代码思路:

    逻辑是基于上面的简化版进行的函数封装,就是使用闭包,把timer包起来。

    然后按照里面的内容拆开写debounce的参数,以上的参数是处理函数handler(就是console.log(123))和delay(时间),如果有更多的业务逻辑,就写更多的参数做封装就行了。

    后话

    这篇博客主要是用来记录一下今天看文档的心得,虽然不多,但是也结合了自己的思考,做个记录,如果您对上面的代码有意见,请在下方评论区帮我优化一下,不慎感激。


    起源地下载网 » 「查漏补缺」定时器与手写防抖debounce

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元