JS的防抖和节流

demo

by Mike Lin

HTML

<script src="https://getfirebug.com/firebug-lite-debug.js"></script>
<button class="throttle">
  throttle
</button>

<button class="debounce">
  debounce
</button>

JavaScript

// throttle的本意是节流,根据配置的时间,稳定地调用回调函数
const throttle = function(fn, waitTime) {
  let timeout = null
  let previous = 0
  let result = 0

  const later = function() {
    result = fn.apply(this, arguments)
    clearTimeout(timeout)
    timeout = null
    previous = Date.now()
  }

  return function() {
    const now = Date.now()
    if (!previous) {
    	previous = Date.now()
    }
    const remaining = waitTime - (now - previous)

    const context = this
    const args = arguments
    if (remaining > 0 && !timeout) {
      timeout = setTimeout(later.bind(context, args), remaining)
    } else if (remaining <= 0) {
      previous = now
      if (timeout) {
        clearTimeout(timeout)
        timeout = null
      }
    }
    return result
  }
}


function debounce(fn, delaytime) {
	let timeout = null
  let contetxt
  let args
  let previous = 0
  let result
  const later = function() {
    const now = Date.now()
    const remaining = delaytime - (now - previous)
    
    if (remaining > 0) {
    	timeout = setTimeout(later.bind(context, args), delaytime)
    } else {
    	result = fn.apply(context, args)
    
      if (timeout) {
        clearTimeout(timeout)
        timeout = null
        context = null
        args = null
      }
    }
  	
  }
	return function() {
    context = this
    args = arguments
    // 只要有触发,那么这里的previous就会一直更新
    previous = Date.now()
    
    if (!timeout) {
    	timeout = setTimeout(later.bind(context, args), delaytime)
    }
    return result
  }
  
}


document.querySelector('.throttle').addEventListener('click', throttle(function(){
	console.log('click event trigger', Date())
}, 1000))

document.querySelector('.debounce').addEventListener('click', debounce(function(){
  console.log('click event trigger', Date())
}, 2000))