防抖和节流
<h3>函数的防抖和节流</h3>
<ul>
<li>什么是防抖?什么是节流?</li>
</ul>
<p><strong>函数防抖(debounce)</strong>:触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间。 提示:最后一次说了算</p>
<h5>应用:</h5>
<ul>
<li>频繁操作点赞和取消点赞,因此需要获取最后一次操作结果并发送给服务器</li>
<li>search搜索联想,用户在不断输入值时,用防抖来节约请求资源。</li>
</ul>
<p><strong>函数节流(throttle)</strong>:高频事件触发,但在n秒内只会执行一次,所以节流会稀释函数的执行频率。 提示:第一次说了算
函数节流(throttle)与 函数防抖(debounce)都是为了限制函数的执行频次,以优化函数触发频率过高导致的响应速度跟不上触发频率,出现延迟,假死或卡顿的现象。</p>
<h5>应用:</h5>
<ul>
<li>鼠标不断点击触发,mousedown(单位时间内只触发一次)</li>
<li>window触发resize的时候,不断的调整浏览器窗口大小会不断的触发这个事件</li>
<li>在页面的无限加载场景下,我们需要用户在滚动页面时,每隔一段时间发一次 Ajax 请求</li>
</ul>
<pre><code class="language-javaScript">/**
* 闭包节流函数方法(可传参数)
* @param Function fn 调用函数
* @param Number delay 延迟多长时间
* @return Function 延迟执行的方法
* 应用 - 鼠标不断点击触发,mousedown(单位时间内只触发一次)
* - window触发resize的时候,不断的调整浏览器窗口大小会不断的触发这个事件
*/
//节流 -> 在n秒钟只执行一次
var throttle = function (fn, delay) {
let canRUn = true ;
return function () {
if(!canRUn){
return ;
}
var args = arguments;
canRUn = false ;
setTimeout(function () {
fn.apply(this, args);
canRUn = true ;
}, delay);
}
}
function postFn(name){
console.log('开始执行'+name)
}
var a = throttle(postFn,3000)('judy');
/**
* debounce 防抖 每次触发事件时都取消之前的延时调用方法
* @param fn 延时调用函数
* @param wait 等待时间
* @return Function 延时执行的方法
* 应用 节约请求资源
* - 频繁操作点赞和取消点赞,因此需要获取最后一次操作结果并发送给服务器
* - search搜索联想,用户在不断输入值时,用防抖来节约请求资源。
*/
function debounce(fn,wait){
let timeout = null ;
return function(){
// 保留调用时的this上下文
let context = this;
// 保留调用时传入的参数
let args = arguments;
if(timeout){
clearTimeout(timeout);
}
timeout = setTimeout(() => {
fn.apply( context,arguments )
},wait)
}
}
var btn = document.getElementById('aa');
btn.onclick = debounce(function(){
sayHi()
},5000)</code></pre>
<p>区别: 函数节流不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数,而函数防抖只是在最后一次事件后才触发一次函数。 比如在页面的无限加载场景下,我们需要用户在滚动页面时,每隔一段时间发一次 Ajax 请求,而不是在用户停下滚动页面操作时才去请求数据。这样的场景,就适合用节流技术来实现。</p>
<h4>vue中使用防抖</h4>
<hr />
<pre><code>//util.js
export const debounce = (fn, wait) => {
let delay = wait|| 500
let timer
return function () {
let args = arguments;
if (timer) {
clearTimeout(timer)
}
let callNow = !timer
timer = setTimeout(() => {
timer = null
}, delay)
if (callNow) fn.apply(this, args)
}
}
//引用
import { debounce } from '@/env/util'
methods:{
refresh:debounce(function(){
this.refreshTypes2('G');
},2000)
}</code></pre>
<p>源文链接:<a href="https://www.cnblogs.com/cathy1024/p/11190081.html">https://www.cnblogs.com/cathy1024/p/11190081.html</a>
原文链接:<a href="https://blog.csdn.net/zuorishu/article/details/93630578">https://blog.csdn.net/zuorishu/article/details/93630578</a></p>