Skip to content

Instantly share code, notes, and snippets.

@riskers
Last active July 20, 2024 15:47
Show Gist options
  • Select an option

  • Save riskers/e3f4369cb2bc6321170410bdde009bbb to your computer and use it in GitHub Desktop.

Select an option

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

riskers commented Sep 24, 2020

Copy link
Copy Markdown
Author

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

riskers commented Oct 19, 2022

Copy link
Copy Markdown
Author

React Hooks

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