函数节流与函数防抖
函数节流
规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效。
适用场景:实现图片懒加载时,给窗口滚动事件挂载回调。其实并不需要实时不断地执行该函数,每200ms执行一次足矣。
/** * [throttle 函数节流] * @param {Function} fn [需要进行函数节流的函数] * @param {Number} wait [函数执行的时间间隔] */ function throttle(fn, wait) { let canRun = true // 首次可执行 return function execute () { if (!canRun) return // 若是false,此处则阻挡 canRun = false // 方法执行前先设置为false,此时若再触发,则会被挡在前面的判断 setTimeout(() => { // 规定时间后执行真正的方法fn fn.apply(this, arguments) canRun = true // 执行完后设置会true, 以便下次可执行 }, wait) } } // 应用示例 function cll() { console.log(window.scrollY) } window.onscroll = throttle(cll, 1000)
函数防抖
在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。
适用场景:搜索框输入关键词后,调取API获取联想词。用户输入停止500ms后再触发回调。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/** * [debounce 函数防抖] * @param {Function} fn [需要进行函数防抖的函数] * @param {Number} wait [需要等待的时间] * @param {Boolean} immediate [调用时是否立即执行一次] */ const debounce = (fn, wait, immediate) => { let timeout = null return function () { if (immediate) { // 事件触发时可立即执行一次 fn.apply(this, arguments) immediate = false // 之后都不再立即触发,此if代码块只执行一次。 } else { clearTimeout(timeout) // 事件不断触发的过程中不断地取消上一个定时器,下面会重新定时。 timeout = setTimeout(() => { // 只有当触发间隔时间超过设定值wait,才有机会执行。否则会被clearTimeout取消掉。但无论如何,最后一次事件触发后最终都会执行一次。 fn.apply(this, arguments) }, wait) } } } const requestHotWords = value => { // 请求API获取相关热搜词 console.log('=xu=你输入的关键词是', value) } const myDelay = debounce(requestHotWords, 1000, false) myDelay({value: '总监'}) // 1秒后输出:=xu=你输入的关键词是 总监
或者
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
const inputEvent = (e) => { debounce(requestHotWords, 1000, null, e.value) } const debounce = (fn, delay, context, value) => { clearTimeout(fn.timeoutId) fn.timeoutId = setTimeout(() => { fn.call(context, value) }, delay) } const requestHotWords = value => { // 请求API获取相关热搜词 console.log('=xu=你输入的关键词是', value) } inputEvent({value: '总监'}) // 1秒后输出:=xu=你输入的关键词是 总监