在事件被触发 n 秒后再执行回调,若是在这 n 秒内又被触发,则从新计时。javascript
好比有一个关键词搜索的input框,用户输入后触发keyup事件向后端发送一个请求:html
<div>
<input id="input" type="text">
</div>
<script> const input = document.getElementById('input') input.addEventListener('keyup', (e) => { console.log(e.target.value) }) </script>
复制代码
测试后能够发现,每次输入都会有打印结果,若是是请求后端接口,那么不只会形成极大的浪费,并且实际应用中,用户也是输出完整的字符后,才会请求。下面咱们优化一下:java
function debounce(fn, delay) {
let timer = null
return function(...args) {
const context = this
if(timer) {
clearTimeout(timer)
}
const _agrs = args.join(',')
timer = setTimeout(fn.bind(context, _agrs), delay)
}
}
const consoleDebounce = debounce(console.log, 500)
const input = document.getElementById('input')
input.addEventListener('keyup', (e) => {
consoleDebounce(e.target.value)
})
复制代码
在运行一次后能够看到,当在频繁的输入时,并不会打印结果,只有当你在指定间隔内没有输入时,才会执行函数。若是中止输入可是在指定间隔内又输入,会从新触发计时。git
function debounce(fn, delay = 500, immediate = false) {
let timer = null
return function(...args) {
const context = this
// 是否当即执行一次
if (immediate && !timer) {
fn.apply(context, args)
}
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
fn.apply(context, args)
}, delay)
}
}
复制代码
指连续触发事件可是在 n 秒中只执行一次函数。 节流会稀释函数的执行频率github
一个 button 按钮,每次点击须要提交表单。面试
<div>
<button id="button">提交</button>
</div>
<script> const button = document.getElementById('button') button.addEventListener('click', (e) => { console.log('click') }) </script>
复制代码
上面代码的问题是,当咱们快速点击 button 时,每次点击都会打印 'click',下面用节流函数优化一下。后端
const conThrottle = throttle(console.log, 2000)
const button = document.getElementById('button')
button.addEventListener('click', (e) => {
conThrottle(1)
})
function throttle(fn, time) {
let timer = null
let flag = true
return function(...args) {
let context = this
if (flag) {
fn.apply(context, args)
flag = false
timer = null
}
if (!timer) {
timer = setTimeout(() => {
flag = true
}, time)
}
}
}
复制代码
再次测试,能够发现无论咱们点击的速度多么快,在每 2 秒内,函数只会执行 1 次。app
function throttle(fn, time) {
let startTime = 0
return function(...args) {
let context = this
let endTime = Date.now()
if (endTime - startTime >= time) {
fn.apply(context, args)
startTime = endTime
}
}
}
复制代码