手写节流和防抖

2024-05-28 04:12
文章标签 手写 节流 防抖

本文主要是介绍手写节流和防抖,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、什么是防抖

定义: 用于限制某个函数在短时间内被频繁调用的情况

特点:

  • 延迟执行:防抖会延迟执行目标函数,直到一定的空闲时间过去后才执行,如果在这段时间内再次触发,则会重新计时。

  • 合并触发:多次连续触发的事件会被合并为一次触发,只有在最后一次触发后的空闲时间内没有再次触发才会执行目标函数。

应用:

  • 输入框实时搜索:在用户输入搜索关键词时,使用防抖可以避免在用户输入过程中频繁触发搜索请求,提高搜索性能和用户体验。

  • 按钮点击事件:在防止用户重复点击按钮后多次触发事件时,可以利用防抖来控制按钮的点击事件,确保只有在用户停止点击后才执行操作。

  • 窗口大小调整:当用户调整窗口大小时,很多页面布局或响应式设计需要重新计算和调整,使用防抖可以确保在用户停止调整窗口大小后再执行相关操作,避免频繁重绘页面。

  • 滚动事件:处理页面滚动事件时,可以利用防抖减少滚动过程中触发的频繁计算,只有在用户滚动停止后才执行相关处理。

优点:

  • 性能优化:防抖可以减少不必要的函数执行次数,降低性能消耗,提高页面性能和响应速度。

  • 用户体验:在一些交互场景下,使用防抖可以有效控制事件触发频率,提升用户体验和界面流畅度。

  • 数据请求控制:在需要向后端发起请求的场景中,防抖可以避免频繁请求数据,减少网络流量和服务器压力。

总的来说,防抖是一种常用的前端技术,通过控制事件触发频率,可以优化性能、提升用户体验,并有效应用于多种交互场景中。

案例:
逻辑梳理:

  • 在这个示例中,debounce函数接受两个参数:需要防抖的函数 func 和延迟时间 delay。返回一个新的函数,用于包裹原始函数 func,并在延迟时间内只允许触发一次执行。

  • 通过调用 debounce(doSomething, 1000) 创建一个防抖函数 debouncedFunction,然后可以多次调用 debouncedFunction,但实际执行的是 doSomething 函数,并且在延迟时间内多次调用会重新计时,只有在延迟时间后才会执行 doSomething 函数。

  • 这样可以确保在需要控制某个函数执行频率的场景下,防抖函数可以帮助避免频繁触发,提升性能和用户体验。

// 防抖函数
function debounce(func, delay) {let timeoutId;return function() {const context = this;const args = arguments;clearTimeout(timeoutId);timeoutId = setTimeout(() => {func.apply(context, args);}, delay);};
}// 示例:模拟一个需要防抖的函数
function doSomething() {console.log('Doing something important!');
}// 创建防抖函数
const debouncedFunction = debounce(doSomething, 1000); // 设置延迟时间为1000毫秒// 调用防抖函数
debouncedFunction(); // 第一次调用
debouncedFunction(); // 在1000毫秒内再次调用
debouncedFunction(); // 在1000毫秒内再次调用

二、什么是节流

定义: 与防抖类似,用于控制某个函数在短时间内被频繁调用的情况
特点:

  • 控制执行频率:节流会确保目标函数在一定时间间隔内只执行一次,即使触发事件多次也不会立即执行,而是在规定的时间间隔后执行。

  • 固定时间间隔:与防抖不同,节流在规定的时间间隔内始终按照固定频率执行函数,不会重新计时。

应用:

  • 页面滚动事件:在处理页面滚动事件时,通过节流可以限制触发频率,比如实现图片懒加载或滚动加载数据。

  • 窗口调整事件:当用户调整窗口大小时,使用节流可以确保在一定时间间隔内执行相关布局调整或响应式设计操作。

  • 按钮点击事件:类似于防抖,节流也可用于控制按钮点击事件的触发频率,确保在一定时间间隔内只执行一次。

  • 用户输入事件:在需要实时反馈用户输入内容的场景中,通过节流可以控制输入事件的处理频率,避免频繁更新UI。

优点:

  • 性能优化:节流可以有效减少函数执行次数,降低性能开销,提高页面性能和响应速度。

  • 流畅交互:通过控制事件执行频率,节流可以确保用户交互过程更加流畅,避免过多的重复操作。

  • 数据请求控制:在需要向服务器请求数据的场景中,节流可以限制请求频率,减少不必要的数据请求,节省网络流量和服务器资源。

总的来说,节流是一种常用的前端技术,通过控制函数执行频率,可以优化性能、提升用户体验,并广泛应用于各种交互场景中。

案例:
逻辑梳理:

  • 在这个示例中,throttle函数接受两个参数:需要节流的函数 func 和间隔时间 delay。返回一个新的函数,用于包裹原始函数 func,并在间隔时间内限制函数的执行频率。

  • 通过调用 throttle(doSomething, 1000) 创建一个节流函数 throttledFunction,然后可以多次调用 throttledFunction,但实际执行的是 doSomething 函数,并且保证在间隔时间内只执行一次。

  • 这样可以确保在需要控制某个函数执行频率的场景下,节流函数可以帮助限制函数的执行频率,避免过多的函数调用,提升性能和用户体验。

// 节流函数
function throttle(func, delay) {let lastCall = 0;return function() {const now = new Date().getTime();if (now - lastCall >= delay) {func();lastCall = now;}};
}// 示例:模拟一个需要节流的函数
function doSomething() {console.log('Doing something important!');
}// 创建节流函数
const throttledFunction = throttle(doSomething, 1000); // 设置间隔时间为1000毫秒// 模拟连续调用节流函数
throttledFunction(); // 第一次调用
throttledFunction(); // 在1000毫秒内再次调用,不会执行
setTimeout(throttledFunction, 500); // 在500毫秒后调用,不会执行
setTimeout(throttledFunction, 1500); // 在1500毫秒后调用,会执行

防抖和节流

function debounce(func, wait, opts = {}) {let maxWait;if ('maxWait' in opts) {maxWait = opts.maxWait;}let leading = true; // 是否在第一次触发时立即执行let trailing = true; // 是否在最后一次触发后执行let lastCallTime; // 上次调用函数的时间let timeout; // 定时器let lastThis; // 函数执行时的 thislet lastArgs; // 函数执行时的参数let lastInvokeTime; // 上次函数实际被调用的时间// 判断是否应该调用函数let shouldInvoke = function (now) {let sinceLastTime = now - lastCallTime;let sinceLastInvoke = now - lastInvokeTime;return lastCallTime === undefined || sinceLastTime > wait || sinceLastInvoke >= maxWait;}// 执行函数let invokeFunc = function (time) {lastInvokeTime = time; // 记录函数实际被调用的时间func.apply(lastThis, lastArgs); // 执行函数}// 启动定时器let startTimer = function (timerExpired, wait) {timeout = setTimeout(timerExpired, wait);}// 计算剩余等待时间let remainingWait = function (now) {return wait - (now - lastCallTime);}// 最后一次触发后执行函数let trailingEdge = function (time) {timeout = undefined;if (trailing) {invokeFunc(time);}}// 定时器到期后的处理逻辑let timerExpired = function () {let now = Date.now();if (shouldInvoke(now)) {return trailingEdge(now);}startTimer(timerExpired, remainingWait(now));}// 第一次触发时执行函数let leadingEdge = function (time) {lastInvokeTime = time;if (leading) {invokeFunc(time);}startTimer(timerExpired, wait); // 开启定时器,准备执行下一次函数调用}// 返回一个处理防抖逻辑的函数let debounced = function (...args) {lastThis = this;lastArgs = args;let now = Date.now();let isInvoking = shouldInvoke(now);lastCallTime = now;if (isInvoking) {if (timeout === undefined) {leadingEdge(now);}}}return debounced;
}

这篇关于手写节流和防抖的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1009512

相关文章

Vue2电商项目(二) Home模块的开发;(还需要补充js节流和防抖的回顾链接)

文章目录 一、Home模块拆分1. 三级联动组件TypeNav2. 其余组件 二、发送请求的准备工作1. axios的二次封装2. 统一管理接口API----跨域3. nprogress进度条 三、 vuex模块开发四、TypeNav三级联动组件开发1. 动态展示三级联动数据2. 三级联动 动态背景(1)、方式一:CSS样式(2)、方式二:JS 3. 控制二三级数据隐藏与显示--绑定styl

stl的sort和手写快排的运行效率哪个比较高?

STL的sort必然要比你自己写的快排要快,因为你自己手写一个这么复杂的sort,那就太闲了。STL的sort是尽量让复杂度维持在O(N log N)的,因此就有了各种的Hybrid sort algorithm。 题主你提到的先quicksort到一定深度之后就转为heapsort,这种是introsort。 每种STL实现使用的算法各有不同,GNU Standard C++ Lib

JS手写实现深拷贝

手写深拷贝 一、通过JSON.stringify二、函数库lodash三、递归实现深拷贝基础递归升级版递归---解决环引用爆栈问题最终版递归---解决其余类型拷贝结果 一、通过JSON.stringify JSON.parse(JSON.stringify(obj))是比较常用的深拷贝方法之一 原理:利用JSON.stringify 将JavaScript对象序列化成为JSO

T1打卡——mnist手写数字识别

🍨 本文为🔗365天深度学习训练营中的学习记录博客🍖 原作者:K同学啊 1.定义GPU import tensorflow as tfgpus=tf.config.list_physical_devices("GPU")if gpus:gpu0=gpus[0]tf.config.experimental.set_memort_groth(gpu0,True) #设置GPU现存用量按需

【DL--22】实现神经网络算法NeuralNetwork以及手写数字识别

1.NeuralNetwork.py #coding:utf-8import numpy as np#定义双曲函数和他们的导数def tanh(x):return np.tanh(x)def tanh_deriv(x):return 1.0 - np.tanh(x)**2def logistic(x):return 1/(1 + np.exp(-x))def logistic_derivati

【tensorflow CNN】构建cnn网络,识别mnist手写数字识别

#coding:utf8"""构建cnn网络,识别mnistinput conv1 padding max_pool([2,2],strides=[2,2]) conv2 x[-1,28,28,1] 卷积 [5,5,1,32] -> [-1,24,24,32]->[-1,28,

【tensorflow 全连接神经网络】 minist 手写数字识别

主要内容: 使用tensorflow构建一个三层全连接传统神经网络,作为字符识别的多分类器。通过字符图片预测对应的数字,对mnist数据集进行预测。 # coding: utf-8from tensorflow.examples.tutorials.mnist import input_dataimport tensorflow as tfimport matplotlib.pyplot

微信小程序手写签名

微信小程序手写签名组件 该组件基于signature_pad封装,signature_pad本身是web端的插件,此处将插件代码修改为小程序端可用。 signature_pad.js /*!* Signature Pad v5.0.3 | https://github.com/szimek/signature_pad* (c) 2024 Szymon Nowak | Released

前端防抖和节流函数的实现原理

在前端开发中,防抖(Debounce)和节流(Throttle)是两种常用的优化技术,它们主要用于减少事件处理函数的执行频率,从而提高程序性能和用户体验。 防抖(Debounce) 防抖的目的是确保一个操作在一段时间内只被执行一次。例如,当用户在一个输入框中快速连续输入文字时,我们可能希望只在用户停止输入之后的一小段时间后再去执行查询操作,以避免频繁触发不必要的API调用。 实现原理: 设

HOW - 支持防抖和远程加载的人员搜索组件(shadcn)

目录 特性一、使用示例二、具体组件实现三、解释1. 属性定义2. 状态管理3. 功能实现4. 渲染逻辑 特性 支持 focus 时即发起请求获取用户列表输入时 debounce 防抖选中后以 tag 形式展示选项,这次点击 x 删除搜索结果中若包含已选项会过滤,即隐藏已选中项支持设置指定选项 disabled 一、使用示例 shadcn - multiple-selecto