节流函数

 //节流函数:如果持续触发事件,每隔一段时间,只执行一次事件,时间戳和定时器两种方式实现

  //1.用时间戳实现:第一次调用时间戳,减去上次的时间戳,当大于wait,则执行函数,并更新上次时间戳,如果
  // 小于,则不执行
  // 第一次调用能立即执行,但是结束调用不能执行最后一次
  function throttleWithDate(func, wait = 1000) {
    let preDate = 0;
    return (args) => {
      let curDate = + new Date(); //把Date对象转化为时间戳,相当于new Date().valueOf()
      console.log('curDate:', curDate);
      if (curDate - preDate > wait) {
        func(args);
        preDate = + new Date();
      }
    }
  }

  function realExecute() {
    console.log('real execute: ' + new Date().valueOf());
  }

  // document.getElementById('testButton')
  // .addEventListener('click', throttleWithDate(realExecute));

  //2.用定时器实现:第一次调用开始计时,下次调用超过了wait时间,则执行函数,重新定时,否则,什么也不干
  //  第一次调用不能立即执行,结束调用还能执行一次
  function throttleWithTimer(func, wait = 1000) {
    let timer = null;
    return (args) => {
      if (!timer) {
        timer = setTimeout(() => {
          func(args);
          timer = null;
        }, wait);
      }
    }
  }

  //3.结合定时器和时间戳,实现第一次调用能立即执行,且结束调用还能最后执行一次
  function throttle(func, wait = 2000) {
    var timer;
    var preDate = 0;

    var throttled = function(args) {
      let curDate = + new Date();
      //下次触发 func 剩余的时间,用于第一次之后的timeout执行定时
      var remaining = wait - (curDate - preDate);
      // 如果调用函数时时间戳,减去上次的时间戳,当大于wait,则执行函数,并更新上次时间戳
      if (curDate - preDate > wait) {
        console.log('时间戳执行');  //第一次执行是时间戳执行
        if (timer) {
          clearTimeout(timer);
          timer = null;
        }
        preDate = curDate;
        func(args);
      } else if (!timer) {  //这里用else,是因为时间戳执行和timeout执行只能有一个执行
        timer = setTimeout(() => {
          console.log('timeout执行'); //除了第一次,之后都是timeout执行
          preDate = +new Date();
          timer = null;
          func(args)
        }, remaining);
      }
    };

    throttled.cancel = function() {
      clearTimeout(timer);
      timer = null;
      preDate = 0;
    };
    return throttled;
  }

  let th = throttle(realExecute);
  document.getElementById('testButton')
    .addEventListener('click', th);
  document.getElementById('cancelButton')
    .addEventListener('click', th.cancel);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值