zoukankan      html  css  js  c++  java
  • js函数防抖、节流实现

    防抖 Debounce

    函数防抖就是,延迟一段时间再执行函数,如果这段时间内又触发了该函数,则延迟重新计算;

    //  简单实现
    function debounce(fn, wait) {
      let t
      return () => {
        let context = this
        let args = arguments
        if (t) clearTimeout(t)
        t= setTimeout(() => {
            fn.apply(context, args)
        }, wait)
      }
    }
    
    // underscore.js debounce
    //
    // Returns a function, that, as long as it continues to be invoked, will not
    // be triggered. The function will be called after it stops being called for
    // N milliseconds. If `immediate` is passed, trigger the function on the
    // leading edge, instead of the trailing.
    
    _.debounce = function(func, wait, immediate) {
      var timeout, args, context, timestamp, result;
    
      // 处理时间
      var later = function() {
        var last = _.now() - timestamp;
    
        if (last < wait && last >= 0) {
          timeout = setTimeout(later, wait - last); // 10ms 6ms 4ms
        } else {
          timeout = null;
          if (!immediate) {
            result = func.apply(context, args);
            if (!timeout) context = args = null;
          }
        }
      };
    

    节流 throttle

    节流:函数间隔一段时间后才能再触发,避免某些函数触发频率过高,比如滚动条滚动事件触发的函数。

    // 简单实现
    function throttle (fn, wait, mustRun) {
      let start = new Date()
      let timeout
      return () => {
        // 在返回的函数内部保留上下文和参数
        let context = this
        let args = arguments
        let current = new Date()
    
        clearTimeout(timeout)
    
        let remaining = current - start
        // 达到了指定触发时间,触发该函数
        if (remaining > mustRun) {
          fn.apply(context, args)
          start = current
        } else {
          // 否则wait时间后触发,闭包保留一个timeout实例
          timeout = setTimeout(fn, wait);
        }
      }
    }
    
    // underscore.js throttle
    //
    // Returns a function, that, when invoked, will only be triggered at most once
    // during a given window of time. Normally, the throttled function will run
    // as much as it can, without ever going more than once per `wait` duration;
    // but if you'd like to disable the execution on the leading edge, pass
    // `{leading: false}`. To disable execution on the trailing edge, ditto.
    
    _.throttle = function(func, wait, options) {
      var context, args, result;
      var timeout = null;
      var previous = 0;
      if (!options) options = {};
      var later = function() {
        previous = options.leading === false ? 0 : _.now();
        timeout = null;
        result = func.apply(context, args);
        if (!timeout) context = args = null;
      };
      return function() {
        var now = _.now();
        if (!previous && options.leading === false) previous = now;
        var remaining = wait - (now - previous);
        context = this;
        args = arguments;
        if (remaining <= 0 || remaining > wait) {
          if (timeout) {
            clearTimeout(timeout);
            timeout = null;
          }
          previous = now;
          result = func.apply(context, args);
          if (!timeout) context = args = null;
        } else if (!timeout && options.trailing !== false) {
          timeout = setTimeout(later, remaining);
        }
        return result;
      };
    };
    
    
  • 相关阅读:
    点分治 / 点分树题目集
    HNOI2019 游记
    WC2019 题目集
    SA / SAM 题目集
    Min_25 筛小结
    NOIP2018 差点退役记
    Atcoder 乱做
    DP及其优化
    计数与概率期望小结
    分库分表之后全局id咋生成?
  • 原文地址:https://www.cnblogs.com/sysuhanyf/p/7514108.html
Copyright © 2011-2022 走看看