-
-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
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
[js] 第115天 分别写出防抖和节流的两个函数,并描述它们分别有什么运用场景? #1043
Comments
type Timeout = number // browser
// type Timeout = NodeJS.Timeout // node
/**
* 防抖:生成一个函数,它在被调用后会等待一段时间再执行。
* 如果在等待期间再次调用,之前还未执行的调用会被取消。
* @param fn 要防抖的函数
* @param timeout 超时时间
*/
function debounce(fn: (...args: any[]) => any, timeout: number) {
let time: Timeout = null
return function _debounced(...args: any[]) {
if (time !== null)
{ clearTimeout(time) }
time = setTimeout(() => {
fn(...args)
time = null
}, timeout)
}
}
/**
* 节流:生成一个函数,它在被调用后一段时间内再次被调用不起作用。
* @param fn 要节流的函数
* @param timeout 超时时间
*/
function throttle(fn: (...args: any[]) => any, timeout: number) {
let time: Timeout = null
return function _throttled(...args: any[]) {
if (time === null) {
fn(...args)
time = setTimeout(() => time = null, timeout)
}
}
} 防止用户高频操作导致事件处理器处理不来。 |
节流:规定在一个单位时间内,只能触发一次函数。
看看楼上带佬代码,看看自己代码,啊!我真菜。 |
|
/**
* 防抖
* @param {Func} callback 需要防抖的函数
* @param {Number} wait 等待毫秒数
*/
function debounce(callback, wait = 0) {
let timer = null
return function () {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
callback.apply(this, arguments)
}, wait)
}
}
/**
* 节流
* @param {Func} callback 需要节流的函数
* @param {Number} wait 等待毫秒数
*/
function throttle(callback, wait = 0) {
let lastTime = null
let nowTime = null
return function () {
nowTIme = Date.now()
if (!lastTime || lastTime - nowTime > wait) {
callback.apply(this, arguments)
lastTime = nowTime
}
}
} |
// 节流: 在操作的一段时间内,函数执行的频率是固定的(定时器形式)
function throttle(foo, hz_ms) {
return function () {
const ctx = this;
const args = arguments;
if (!throttle.id) {
throttle.id = setTimeout(() => {
foo.apply(ctx, args)
throttle.id = null;
}, hz_ms);
}
}
}
// 防抖: 频繁的操作完成之后,再执行对应的函数;
function debounce(foo, lay_ms) {
return function () {
clearTimeout(debounce.id);
const that = this;
const args = arguments;
debounce.id = setTimeout(() => {
foo.apply(that, args);
}, lay_ms);
}
}
function handler() {
console.log(111);
}
// document.onmousemove = debounce(handler, 1000)
document.onmousemove = throttle(handler, 1000) |
你的可读性比较好,这也是代码的优点之一 |
节流(throttle)
function throttle(fn, delay) {
let last = 0 // 这样能保证第一次触发能够立即被执行
return function throttle_fn() {
if(Date.now() - last >= delay) {
fn.apply(this, arguments)
last = Date.now()
}
}
} 主要是记录上一次执行的时间戳,然后与当前时间戳进行比较,若超过指定的时间则执行一次;
function throttle2(fn, delay) {
let last = null
return function throttle_fn() {
if(last === null) {
last = setTimeout(() => {
fn.apply(this, arguments)
last = null // 清除已执行的计时器标记
}, delay)
}
}
} 该方法主要利用计数器的标记进行节流,计时器在执行完一次操作之前标记不会被处理,因此在规定时间内的其它操作都不会被执行,从而达到了规定时间内只执行一次的目的。 防抖(debounce)
可以利用计时器延迟事件的执行来实现: function debounce(fn, delay) {
let last = null
return function debounce_fn() {
if(last) {
clearTimeout(last) // 若此时距离上次执行的时间小于delay,就相当于取消了前一次执行
}
last = setTimeout(() => {
fn.apply(this, arguments)
}, delay) // 事件延迟执行,只有当后一次触发与当前触发≥delay时才会被执行!
}
} 由于每次触发都会执行 |
在我看来,防抖与节流都是控制函数调用频率的手段。两者的主要的区别是:在给定时间间隔内调用多次时,防抖采用最新调用而节流采用首次调用。 |
节流没必要用定时器,我被面试官问到过 |
防抖函数 限定多少时间只能执行一次 执行多次取最后一次执行
节流就是在一段时间内相同的事件只处理一次
|
节流函数
防抖函数
|
/**
* 节流函数
* */
function throttle(fn, delay, scope) {
let timer;
return function () {
let context = scope || this, args = arguments;
if (!timer) {
timer = setTimeout(() => {
fn.apply(context, args);
timer = null;
}, delay)
}
}
}
/**
* 防抖函数
* */
function debounce(fn, delay, scope) {
let timer;
return function () {
let context = scope || this, args = arguments;
clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(context, args);
}, delay)
}
} |
/**
/** |
第115天 分别写出防抖和节流的两个函数,并描述它们分别有什么运用场景?
The text was updated successfully, but these errors were encountered: