10. 函数防抖 
对指定函数进行处理,使得函数 秒后执行且只会执行一次,如果 秒内事件再次触发,则会重新计时。
js
/**
 * @param {Function} func
 * @param {number} wait
 */
function debounce(func, wait) {
  let timeout
  return function () {
    const context = this
    const args = arguments
    clearTimeout(timeout)
    timeout = setTimeout(() => {
      func.apply(context, args)
    }, wait)
  }
}
const node = document.getElementById('layout')
function getUserAction(e) {
  console.log(this, e)
  node.innerHTML = count++
};
node.onmousemove = debounce(getUserAction, 1000)测试代码:
js
/**
 * @param {Function} func
 * @param {number} wait
 */
function debounce(func, wait) {
  let timeout
  return function () {
    const context = this
    const args = arguments
    clearTimeout(timeout)
    timeout = setTimeout(() => {
      func.apply(context, args)
    }, wait)
  }
}
const node = document.getElementById('layout')
function getUserAction(e) {
  console.log(this, e)
  node.innerHTML = count++
};
最终版:除了支持 this 和 event 外,还支持以下功能:
- 支持立即执行
- 函数可能有返回值
- 支持取消功能
js
export function debounce(func, wait, immediate) {
  let timeout, result
  const debounced = function () {
    const context = this
    const args = arguments
    if (timeout)
      clearTimeout(timeout)
    if (immediate) {
      // 如果已经执行过,不再执行
      const callNow = !timeout
      timeout = setTimeout(() => {
        timeout = null
      }, wait)
      if (callNow)
        result = func.apply(context, args)
    }
    else {
      timeout = setTimeout(() => {
        func.apply(context, args)
      }, wait)
    }
    return result
  }
  debounced.cancel = function () {
    clearTimeout(timeout)
    timeout = null
  }
  return debounced
}