Skip to content

Instantly share code, notes, and snippets.

@riskers
Last active July 20, 2024 15:47
Show Gist options
  • Save riskers/e3f4369cb2bc6321170410bdde009bbb to your computer and use it in GitHub Desktop.
Save riskers/e3f4369cb2bc6321170410bdde009bbb to your computer and use it in GitHub Desktop.
throttle and debounce

throttle 节流

定义了一个函数一段时间内的最多执行次数,比如『执行某函数最多每100ms执行一次』

type AnyFunction = (...args: any[]) => void;
const throttle = <T extends AnyFunction>(fn: T, delay: number): (...args: Parameters<T>) => void => {
  let last = 0;

  return (...args: Parameters<T>): void => {
    const now = Date.now();

    if (now - last > delay) {
      last = now;
      fn(...args);
    }
  };
};

debounce 防抖

定义了一个函数在一定时间过去再被调用。比如『执行这个函数在没有被调用的100ms之后再调用』

type AnyFunction = (...args: any[]) => void;
const debounce = <T extends AnyFunction>(fn: T, delay: number): (...args: Parameters<T>) => void => {
  let timeId: ReturnType<typeof setTimeout> | null = null;

  return (...args: Parameters<T>): void => {
    if (timeId !== null) {
      clearTimeout(timeId);
    }

    timeId = setTimeout(() => {
      fn(...args);
    }, delay);
  };
};

使用

basic

// 在 `onresize` 事件中每隔 `delay` 就会触发一次 console
window.onresize = throttle(function() {
  console.log(1)
}, 1000)

// 在停止 `onpress` 事件后隔 `delay` 触发一次 console
input.onpress = debounce(function(e) {
  console.log(e.target.value)
}, 1000)

pass params

var callback = debounce(function(xx){
    console.log(xx)
}, 1000)
window.onresize = function() {
    callback('value')
}
@riskers
Copy link
Author

riskers commented Sep 29, 2016

@riskers
Copy link
Author

riskers commented Jan 11, 2019

lodash

window.onresize = _.throttle(function(){
  console.log(1)
},1000)
window.onresize = _.debounce(function(){
  console.log(1)
},1000)

@riskers
Copy link
Author

riskers commented Sep 24, 2020

application in React

重点是把同步的和要 debounce/throttle 的异步函数分开,并且在 constructor 阶段就把 debounce/throttle 部分做好。

import debounce from 'lodash/debounce'

class T extends React.Component {
  constructor(props) {
    super(props)
    this.debounceOnChange = debounce(this.deOnChange, 300)
  }
                                 
  onChange = (e) => {
    e.persist()
    /**
     * something sync:
     *
     *  this.setState({
     *
     *  })
    **/
    
    // something async:
    this.debounceOnChange(e)
  }

  debounceOnChange = (e) => {
    //fetch(...)
  }
  
  render() {
    return(
      <input onChange={this.onChange} />
    )
  }
}

@riskers
Copy link
Author

riskers commented Oct 19, 2022

React Hooks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment