01、防抖还是节流

防抖节流 目的都是避免一定时间内,大量重复的操作造成的性能损耗。因此原理也类似,都是阻止过多的事件执行,只保留一部分来执行。适用场景略有不同,也有交叉,动手练习一遍就懂了。

区别 防抖(Debounce) 节流(throttle)
描述 一定延迟时间内,连续事件只执行最后一次 一段固定时间内只执行一次
原理 只保留一个延时setTimeout()的执行器,后续新的替代旧的 判断时间间隔,在固定间隔时间内,只执行一次。
执行次数 只执行最后一次 执行首次、最后一次,或首次+最后一次
合适场景 连续操作只需要一次的,如变更内容提交到后端 连续操作定期执行的场景:连续的UI交互,如拖拽、滚动

02、什么是防抖(Debounce)?

按字面意思理解就是 防止抖动(Debounce /di'bauns/ 防抖动),本来只需要点击一次,结果手抖操作了很多次,重复执行就造成了额外的浪费。

防抖函数的原理:在一定延迟时间内,连续触发的事件合并只执行 最后 一次。技术原理是用闭包保存一个延时执行函数setTimeout(func, delayTime)返回变量,只要延迟时间delayTime内新触发的执行器,就会代替旧执行器。

实现代码

/******************************   防抖函数  ******************************/
//参数func:需要防抖的函数
//参数delayTime:延时时长,单位ms
function debounce(func, delayTime) {
//用闭包路缓存延时器id
let timer;
return function (...args) {
if (timer)
clearTimeout(timer); //清除-替换,把前浪拍死在沙滩上
timer = setTimeout(() => {
func.apply(this, args);
}, delayTime);
}
}

适用场景

  • 提交按钮,避免重复点击提交数据,只执行最后一次。
  • 文本框输入的响应:如基于输入文本服务端联想查询,对输入内容的服务端验证等,防抖就可以避免没必要的请求,节约资源。
  • 连续触发的事件,如窗口的resize事件、窗口的滚动scroll事件,只处理最后一次。

使用案例:滚动浏览器滚动条到末尾。

  • 如果不用防抖函数,scroll事件频繁触发,共触发了29次。
  • 加上防抖函数,同样的速度移动,只触发了最后一次。
//移动浏览器滚动条到末尾,无防抖
window.addEventListener('scroll', print); //执行了29次
//加上防抖,延迟300ms
window.addEventListener('scroll', debounce(print, 300)); //执行了1次
let index = 0;
function print() {
console.log(index++);
}

03、为何要节流(throttle)?

节流(throttle)字面意思就是节约流量(throttle /ˈθrɑːtl/ 节流阀),一个小朋友一分钟只能吃一勺饭,每分钟喂了30勺,喂得太快要么食物浪费了,要么被噎到。

节流函数的原理:一定时间内只执行一次事件,在一段时间intervalTime内,不管触发了多少次事件(大于1)都只执行一次。

  • 因此首先需要判断间隔时间,是否在间隔时间内。
  • 具体执行的时机,可选择首次,也可以选择最后一次,或者首次+最后一次。

实现代码:三种实现方式

  • 实现1:单位时间内执行第一次(立即执行),节流后面的,基于时间间隔判断。
  • 实现2:单位时间内执行第一次(延迟执行),节流后面的,基于延时函数setTimeout()
  • 实现3:执行首次+最后一次,节流中间的,比较综合全面的的实现方式!
// 实现1:单位时间内执行第一次(立即执行),节流后面的
function throttle(func, intervalTime = 100) {
let lastTime = 0;
return (...args) => {
let now = Date.now();
//首次调用会执行
if (now - intervalTime > lastTime) {
func.apply(this, args);
lastTime = now;
}
}
}
// 实现2:单位时间内执行第一次(延迟执行),节流后面的
const throttle2 = (func, intervalTime = 100) => {
// 定义falg,初试为true
let flag = true;
// 返回的函数是每次用户实际调用的节流函数
return (...args) => {
const ctx = this;
// 如果flag为true,则执行定时器
if (flag) {
setTimeout(() => {
func.apply(ctx, args);
// 函数执行完毕后=true;
flag = true;
}, intervalTime);
}
//没执行完成前都为false
flag = false;
};
}
// 实现3:执行首次+最后一次,节流中间的,比较综合的节流方式!
function throttleMiddle(func, intervalTime = 100) {
let timer = null;
let startTime = 0;
return (...args) => {
const ctx = this;
const now = Date.now();
if (startTime && now < startTime + intervalTime) {
//替换前面的
clearTimeout(timer);
timer = setTimeout(() => {
startTime = now;
func.apply(ctx, args);
}, Math.max(intervalTime - (Date.now() - startTime), 0)); //剩余等候时间
} else { //每轮首次会执行,立即执行
startTime = now;
func.apply(ctx, args);
}
}
}
// 节流-函数扩展,使用的throttleMiddle版本
Function.prototype.throttle = function (intervalTime = 100) {
let func = this;
let startTime, timer = null;
//这里不能用箭头函数,会导致this污染
return function (...args) {
const ctx = this;
let now = Date.now();
if (startTime && now < startTime + intervalTime) {
clearTimeout(timer);
timer = setTimeout(() => {
func.apply(this, args);
startTime = now;
}, Math.max(intervalTime - (now - startTime), 0));
}
else {
startTime = now;
func.apply(ctx, args);
}
}
}

适用场景

  • 定时秒杀、抽奖按钮,运行多次提交,避免太过频繁的提交把服务端搞崩了。
  • 连续的UI交互,如DOM拖拽,在窗口的resize事件、窗口的滚动scroll事件中更新UI,如果用防抖会有卡顿的现象,更适合用节流。

使用案例:滚动浏览器滚动条到末尾。

  • 如果不用防抖函数,scroll事件频繁触发,共触发了29次。
  • 加上节流函数,同样的速度移动,执行了4次,间隔均匀。
//移动浏览器滚动条到末尾
window.addEventListener('scroll', print); //执行了29次
//加上节流,延迟300ms
window.addEventListener('scroll', throttle(print, 300)); //执行了4次
let index = 0;
function print() {
console.log(index++);
}

️版权申明:版权所有@安木夕,本文内容仅供学习,欢迎指正、交流,转载请注明出处!原文编辑地址-语雀

JavaScript中的防抖与节流-图文版的更多相关文章

  1. 来聊聊JavaScript中的防抖和节流

    目录 JavaScript防抖和节流 问题还原 防抖 什么是防抖 使用场景 节流 什么是节流 使用场景 JavaScript防抖和节流 问题还原 我们先来通过代码把常见的问题还原: <html& ...

  2. JavaScript 中的防抖和节流

    什么是防抖 函数防抖(debounce):当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时.如下图,持续触发 scrol ...

  3. JavaScript中函数防抖、节流

    码文不易,转载请带上本文链接,感谢~ https://www.cnblogs.com/echoyya/p/14565642.html 目录 码文不易,转载请带上本文链接,感谢~ https://www ...

  4. JS中的防抖与节流

    什么是防抖?and什么是节流?一起来开心的学习下吧. 首先什么是防抖:就是在一定的时间内事件只发生一次,比如你点击button按钮,1秒内任你单身30年手速点击无数次,他也还是只触发一次.举个例子,当 ...

  5. Js中的防抖与节流函数

    1.何为防抖与节流函数呢? 1.防抖(debounce):通过setTimeout方式,在一定的时间间隔内,将多次触发的事件转化为一次触发.也就是说当一个用户一直触发这个函数,且每次触发函数的间隔小于 ...

  6. JS中的防抖和节流

    JS-防抖和节流 在进行窗口的resize.scroll,输入框内容校验等操作时,如果事件处理函数调用的频率无限制,会加重浏览器的负担,导致用户体验非常糟糕.此时我们可以采用debounce(防抖)和 ...

  7. JavaScript函数的防抖和节流

    防抖 触发高频事件后n秒内函数只会执行一次,如果n秒内高频事件再次被触发,则重新计算时间 思路: 每次触发事件时都取消之前的延时调用方法 function debounce(fn) { let tim ...

  8. 输入防抖 vue # 输入搜索的时候 及时搜索的快速访问接口的 解决方案 vue 中使用防抖和节流

    输入防抖 watch: { value (newVal, oldVal) { if (this.timer) { clearTimeout(this.timer) } this.timer = set ...

  9. 理解Linux系统中的load average(图文版)转

    一.什么是load average? linux系统中的Load对当前CPU工作量的度量 (WikiPedia: the system load is a measure of the amount ...

  10. 理解Linux系统中的load average(图文版)

    本文转自:http://heipark.iteye.com/blog/1340384 一.什么是load average? linux系统中的Load对当前CPU工作量的度量 (WikiPedia: ...

随机推荐

  1. 【前端必会】webpack loader 到底是什么

    概述 webpack的使用中我们会遇到各种各样的插件.loader. webpack的功力主要体现在能理解各个插件.loader的数量上.理解的越多功力越深 loader是什么呢? 背景 了解load ...

  2. 一键体验 Istio

    背景介绍 Istio 是一种服务网格,是一种现代化的服务网络层,它提供了一种透明.独立于语言的方法,以灵活且轻松地实现应用网络功能自动化.它是一种管理构成云原生应用的不同微服务的常用解决方案.Isti ...

  3. Go | 讲解GOROOT、GOPATH、GOBIN

    前言 Go(又称 Golang)是 Google 开发的一种静态强类型.编译型.并发型,并具有垃圾回收功能的编程语言.Go 被誉为是未来的服务器端编程语言. Go是一门全新的静态类型开发语言,具有自动 ...

  4. 齐博x1文本代码标签的使用

    文本标签虽然简单,但是使用的地方确实非常多的. {qb:tag name="XXXX" type="text"}推荐新闻{/qb:tag} 类似这种使用的频率是 ...

  5. C语言/python实现定时关机

    1.python def shutdown(): print('(1)定时关机\n(2)取消定时关机\n(3)立即关机\n(4)关机重启') b = eval(input('请选择:\n')) if( ...

  6. Codeforces Round #553 (Div. 2)/codeforces1151

    CodeForces1151 Maxim and Biology 解析: 题目大意 每次可以使原串中的一个字符\(+1/-1\),\(Z + 1\to A, A -1\to Z\),求至少修改多少次可 ...

  7. 9.channels layers

    settings.py配置 # 存储在内存里 CHANNEL_LAYERS = { "default": { "BACKEND": "channels ...

  8. C# RulesEngine 规则引擎:从入门到看懵

    说明 RulesEngine 是 C# 写的一个规则引擎类库,读者可以从这些地方了解它: 仓库地址: https://github.com/microsoft/RulesEngine 使用方法: ht ...

  9. Selenium4+Python3系列(五) - 多窗口处理之句柄切换

    写在前面 感觉到很惭愧呀,因为居然在Selenium+Java系列中没有写过多窗口处理及句柄切换的文章,不过也无妨,不管什么语言,其思路是一样的,下面我们来演示,使用python语言来实现窗口句柄的切 ...

  10. 如何免安装使用 Python?推荐 17 个在线的 Python 解释器!

    作者:Al Sweigart 译者:豌豆花下猫@Python猫 英文:https://inventwithpython.com/blog/2022/10/30/17-online-python-ide ...