一. 应用场景
当前问题:

现在点击一个按钮,然后会向服务器请求一次数据。如果暴力操作,不断的点击按钮,那么就会一直向服务器请求,这样肯定不好,需要应用到防抖函数

最终目的:多次触发只执行最后一次或者只执行第一次

① 在点击很多次以后,我们只希望执行最后一次。
② 在点击很多次以后,我们只希望执行第一次。

二. 遇到困难

防抖函数,大家写的也够多了,最普遍的写法如下:

function debounce(fnc, delay=3000) {let timer = null; // 创建一个用来存放定时器的变量return function () {clearTimeout(timer); //只要触发就清除timer = setTimeout(() => {fnc.apply(this, arguments);}, delay);};
}

但是很遗憾的是,这种写法的防抖函数并没有效果。假如延迟时间设置的3000毫秒,然后我连续点击5次,表面上看起来是成功了。实际上并没有,3秒后,你传入的函数会执行5次。

不信吗?那我们写个例子来试试看呢

<template><div><p @click="testDebounce">测试防抖</p></div>
</template><script>
export default {methods: {testDebounce() {console.log('我点击了')this.debounce(this.testFnc, 3000)();},testFnc() {console.log('执行了传入的函数testFnc');},debounce(fnc, delay=3000) {let timer = null; // 创建一个用来存放定时器的变量return function () {clearTimeout(timer); //只要触发就清除timer = setTimeout(() => {console.log('定时器函数执行了')fnc.apply(this, arguments);}, delay);};}}
}
</script>

我点击了5次,刚开始控制台没打印,3秒过后打印了5次,如下:

未生效原因:每次点击时,debounce里面的timer并不是共用的而是独立的,也就是每点击一次就会为当前点击创建一个timer,所以你点击5次,就生成了5个timer,这5个之间相互不会影响,那么最后打印执行了5次。

三. 解决办法

知道了原因以后就比较好解决了,在实际应用中,我们都会将防抖之类的公共函数封装在js文件里。

下面我就写在debounce.js里面,测试如下:

① 在点击很多次以后,我们只希望执行最后一次。
1.debounce.js文件里let debounceTimer = null;
export function debounce(callback, duration) {return function (...args) {let ctx = this;if (debounceTimer) clearTimeout(debounceTimer);debounceTimer = setTimeout(() => {console.log('定时器函数执行了')callback.apply(ctx, args);}, duration);};
};2.test组件里面<template><div><p @click="testDebounce">测试防抖</p></div>
</template><script>
import { debounce } from '../utils/debounce.js'export default {methods: {testDebounce() {console.log('我点击了')debounce(this.testFnc, 3000)()},testFnc() {console.log('执行了传入的函数testFnc')},},
}
</script>

结果如下图:我连续点击了5次,只执行了最后一次。

② 在点击很多次以后,我们只希望执行第一次或者执行最后一次,由我们来控制。
debounce.js文件里 (例子不再贴出,根据上面的替换就行)let debounceTimer = null;
export function debounce(callback, duration, isFirstExecution) {return function (...args) {let ctx = this;const delay = function () {debounceTimer = null;console.log('定时器函数执行了')if (!isFirstExecution) callback.apply(ctx, args);};let executeNow = isFirstExecution && !debounceTimer;clearTimeout(debounceTimer);debounceTimer = setTimeout(delay, duration);if (executeNow) callback.apply(ctx, args);};
};
// isFirstExecution为true时只执行第一次,为false时只执行最后一次

上面两个方法的关键点就是把接收定时器变量的定义提到了函数外面,变量名尽量取得特别点,不然在组件引入的时候可能有报变量名相同的风险。
(完)

---------------------------------------------------------- 补充 -----------------------------------------------------

var 声明变量时,变量会提升

let 声明变量时,存在局部作用域

所以在( 二. 遇到困难)里面的timer改为var来声明的话就不会再有上面所说的问题

function debounce(fnc, delay=3000) {var timer = null; // 创建一个用来存放定时器的变量return function () {clearTimeout(timer); //只要触发就清除timer = setTimeout(() => {fnc.apply(this, arguments);}, delay);};
}

防抖函数:多次触发后只执行第一次或者最后一次的函数相关推荐

  1. 嵌套点击事件只执行第一次

    如下点击"哈哈哈"的时候只触发f2也就是弹出2,不弹出1 <a onclick='f1()'><div><span onclick="f2( ...

  2. c语言中执行一次的函数once,iOS只执行一次的方法

    IOS开发(64)之GCD任务最多只执行一次 1 前言 使用 dispatch_once 函数 在 APP 的生命周期内来保证你想确保每段代码只执行一次,即使它在代码的不同地方多次调用(比如单例的初始 ...

  3. 微信小程序云函数中的数据处理后返回

    微信小程序云函数中的数据处理后返回 本文主要演示的是,在微信云函数中调用数据库后,如何对获取的内容在云函数内处理后返回. 主函数 exports.main = async (event, contex ...

  4. Go 学习笔记(19)— 函数(05)[如何触发 panic、触发 panic 延迟执行、panic 和 recover 的关系]

    1. 异常设计思想 Go 语言的错误处理思想及设计包含以下特征: 一个可能造成错误的函数,需要返回值中返回一个错误接口( error ),如果调用是成功的,错误接口将返回 nil ,否则返回错误. 在 ...

  5. 基于c++和asio的网络编程框架asio2教程基础篇:2、各个回调函数的触发顺序和执行流程

    基于c++和asio的网络编程框架asio2教程基础篇:2.各个回调函数的触发顺序和执行流程 以tcp举例: tcp服务端流程: #include <asio2/asio2.hpp>int ...

  6. 定时任务重启后执行策略_C语言操作时间函数time.ctime,实现定时执行某个任务小例子...

    时间操作函数在实际项目开发中会经常用到,最近做项目也正好用到就正好顺便整理一下. 时间概述 由上图可知: 通过系统调用函数time()可以从内核获得一个类型为time_t的1个值,该值叫calenda ...

  7. 微信小程序 - 返回前一个页面时,执行前一个页面的函数方(wx.navigateBack 返回后,执行上一页的某个函数方法刷新数据)回前一个页面时,执行前一个页面的函数方法。支持改变 data 数据。

    前言 例如,您使用 wx.navigateTo 跳转到页面后,当用户点击左上角返回时,您需要执行上一页的函数来达到更新数据或改变数据. 比如 当付款完成后,从页面返回查看订单时,订单列表此时数据必须是 ...

  8. winform 让他间隔一段时间 执行事件 且只执行一次_Redis 事件机制详解

    点击上方"程序员历小冰",选择"置顶或者星标" 你的关注意义重大! Redis 采用事件驱动机制来处理大量的网络IO.它并没有使用 libevent 或者 li ...

  9. java接口防抖_前端性能优化:高频执行事件/方法的防抖

    日期:2013-6-25  来源:GBin1.com 高频执行事件/方法的防抖 通常,开发人员会在有用户交互参与的地方添加事件,而往往这种事件会被频繁触发.想象一下窗口的resize事件或者是一个元素 ...

最新文章

  1. [VBScript] 自动删除2小时以前生成的文件
  2. 微信的通讯录首字母滑动的实现
  3. 一种基于FPGA 的1080p 高清多摄像头全景视频拼接的泊车(机)
  4. 洛谷 1608 路径统计
  5. python矩阵相加_【python矩阵相加怎么做,这可是证明python功能的大好机会】- 环球网校...
  6. C++读取配置文件的写法
  7. Tomcat version 7.0 only supports J2EE 1.2, 1.3, 1.4, and Java EE 5 and 6 Web
  8. 判断条件要仔细推敲(记洛谷P1317题WA的经历,Java语言描述)
  9. clickhouse注入的利用
  10. 基于Vue.js 2.x系列 + Element UI + RBAC/AUTH权限 的响应式后台管理系统
  11. Python身份证号码识别
  12. 史上最搞笑的程序员段子,有图有真相!
  13. 使用nodejs + wecharty打造你的个人微信机器人
  14. starUML for MAC 破解方法
  15. MATLAB中输出直观公式
  16. 百度AI战疫五十天:三场战役与一次胜利
  17. 电脑设备管理器无端口显示怎么办?
  18. 关于Windows PowerShell
  19. Python|简易银行ATM程序制作
  20. H264_Lite高清视频编码器/解码器IP核(FPGA/ASIC通用)

热门文章

  1. Vundle(Vim bundle) 是一个vim的插件管理器。
  2. Github上找好东西的方法
  3. 【内有福利】5.7K画质高品质防抖:运动全景相机开启新纪元
  4. 华为OD机试真题 C++ 实现【异常的打卡记录】【2022.11 Q4 新题】
  5. 安徽IP地址段(续)
  6. vmware 虚拟工作平台(虚拟机--客户机) ---物理机(宿主机)
  7. JVM(运行时数据区结构)详解一
  8. 如何对用户输入进行校验
  9. 入职阿里啦!字节大牛耗时八个月又一力作,Java面试真题精选
  10. 迁出X86架构,你准备好了吗?