We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
某个函数在某段时间内,无论触发了多少次回调,都只执行最后一次
function debounce(fn, wait) { // 缓存一个定时器id let timeout = null return function(..args) { let _self = this // 如果已经设定过定时器就清空上一次的定时器 if (timeout !== null) { clearTimeout(timeout) } timeout = setTimeout(() => { fn.apply(_self, args) }, wait) } }
function debounce(fn, wait, immediate) { // 定义一个时间器id let timeout = null return function(...args) { let _self = this // 如果有时间器id就清除 if (timeout !== null) { clearTimeout(timer) } // 实现第一次出发毁掉事件执行 if (immediate && !timeout) { fn.apply(_self, args) } timeout = setTimeout(() => { fn.apply(_self, args) }, wait) } }
节流指的是某个函数在一定时间间隔内(例如 3 秒)执行一次,在这 3 秒内 无视后来产生的函数调用请求
节流适用于函数调用频繁的场景, 例如 window.onreisze, mousemove, 上传进度等
window.onreisze
mousemove
记录上次时间戳
当前时间戳
上次时间戳
时间差
1000s
function throttle(fn, wait) { let last = 0 return function(...args) { let _self = this let now = +new Date() if (now - last > wait) { last = now fn.apply(_self, args) } } }
function throttle(fn, wait) { let timeout = null let last = 0 return function(...args) { let _self = this let now = +new Date() if (last && now - last < wait) { if (timeout !== null) { clearTimeout(timeout) } timeout = setTimeout(() => { last = now fn.apply(_self, args) }, wait) } else { last = now fn.apply(_self, args) } } }
const throttle = function(func, wait, options) { var timeout, context, args, result; // 上一次执行回调的时间戳 var previous = 0; // 无传入参数时,初始化 options 为空对象 if (!options) options = {}; var later = function() { // 当设置 { leading: false } 时 // 每次触发回调函数后设置 previous 为 0 // 不然为当前时间 previous = options.leading === false ? 0 : _.now(); // 防止内存泄漏,置为 null 便于后面根据 !timeout 设置新的 timeout timeout = null; // 执行函数 result = func.apply(context, args); if (!timeout) context = args = null; }; // 每次触发事件回调都执行这个函数 // 函数内判断是否执行 func // func 才是我们业务层代码想要执行的函数 var throttled = function() { // 记录当前时间 var now = _.now(); // 第一次执行时(此时 previous 为 0,之后为上一次时间戳) // 并且设置了 { leading: false }(表示第一次回调不执行) // 此时设置 previous 为当前值,表示刚执行过,本次就不执行了 if (!previous && options.leading === false) previous = now; // 距离下次触发 func 还需要等待的时间 var remaining = wait - (now - previous); context = this; args = arguments; // 要么是到了间隔时间了,随即触发方法(remaining <= 0) // 要么是没有传入 {leading: false},且第一次触发回调,即立即触发 // 此时 previous 为 0,wait - (now - previous) 也满足 <= 0 // 之后便会把 previous 值迅速置为 now if (remaining <= 0 || remaining > wait) { if (timeout) { clearTimeout(timeout); // clearTimeout(timeout) 并不会把 timeout 设为 null // 手动设置,便于后续判断 timeout = null; } // 设置 previous 为当前时间 previous = now; // 执行 func 函数 result = func.apply(context, args); if (!timeout) context = args = null; } else if (!timeout && options.trailing !== false) { // 最后一次需要触发的情况 // 如果已经存在一个定时器,则不会进入该 if 分支 // 如果 {trailing: false},即最后一次不需要触发了,也不会进入这个分支 // 间隔 remaining milliseconds 后触发 later 方法 timeout = setTimeout(later, remaining); } return result; }; // 手动取消 throttled.cancel = function() { clearTimeout(timeout); previous = 0; timeout = context = args = null; }; // 执行 _.throttle 返回 throttled 函数 return throttled; };
例如 3 秒, 在这 3 秒内无视后来产生的函数调用请求
The text was updated successfully, but these errors were encountered:
No branches or pull requests
debounce
某个函数在某段时间内,无论触发了多少次回调,都只执行最后一次
实现第一次触发回调事件就执行 fn
thorttle
节流指的是某个函数在一定时间间隔内(例如 3 秒)执行一次,在这 3 秒内 无视后来产生的函数调用请求
节流适用于函数调用频繁的场景, 例如
window.onreisze
,mousemove
, 上传进度等实现原理
记录上次时间戳
,每次触发事件回调,判断当前时间戳
距离上次时间戳
的间隔是否已经达到了时间差
, 如果是就执行,并更新上次时间戳,如此循环1000s
的的定时器,每次触发事件回调,如果定时器存在,则回调方法不执行,直到定时器触发,hander被清除,重新设置定时器 (可以理解成一个防抖debounce)时间戳来判断
时间戳 + 定时器
undrscore throttle
总结
例如 3 秒, 在这 3 秒内无视后来产生的函数调用请求
The text was updated successfully, but these errors were encountered: