防抖 节流 防抖和节流

防抖和节流可以通过使用 Lodash 库中的 debounce 和 throttle 方法来实现。

防抖(debounce) 是指在一定时间内,如果事件持续触发,则只执行最后一次事件。常用于输入框搜索、滚动加载等场景。 回城

节流(throttle) 是指在一定时间内,无论事件触发多少次,只执行一次事件。常用于滚动事件、窗口大小改变等场景。普攻

一、方法封装

javascript 复制代码
export const debounce = (fn, delay = 0, immediate = false) => {
    let timeout;
    return (...args) => {
        if (immediate && !timeout) fn(...args);
        clearTimeout(timeout);

        timeout = setTimeout(() => {
            fn(...args);
        }, delay);
    };
};
// 节流函数
export const throttle = (func, delay) => {
    let timeoutId;
    let lastExecTime = 0;

    return function (...args) {
        const currentTime = Date.now();

        if (currentTime - lastExecTime < delay) {
            // 上次执行时间距当前时间未超过指定延迟,不执行函数
            clearTimeout(timeoutId);
            timeoutId = setTimeout(() => {
                lastExecTime = currentTime;
                func.apply(this, args);
            }, delay);
        } else {
            // 上次执行时间距当前时间已超过指定延迟,立即执行函数
            lastExecTime = currentTime;
            func.apply(this, args);
        }
    };
}

或者

javascript 复制代码
/**
 * @desc 函数防抖
 * @param func 目标函数
 * @param wait 延迟执行毫秒数
 * @param immediate true - 立即执行, false - 延迟执行
 */
export const debounce = function(func, wait = 1000, immediate = true) {
	let timer;
	console.log(1);
	return function() {
		console.log(123);
		let context = this,
			args = arguments;
		if (timer) clearTimeout(timer);
		if (immediate) {
			let callNow = !timer;
			timer = setTimeout(() => {
				timer = null;
			}, wait);
			if (callNow) func.apply(context, args);
		} else {
			timer = setTimeout(() => {
				func.apply(context, args);
			}, wait)
		}
	}
}
/**
 * @desc 函数节流
 * @param func 函数
 * @param wait 延迟执行毫秒数
 * @param type 1 使用表时间戳,在时间段开始的时候触发 2 使用表定时器,在时间段结束的时候触发
 */
export const throttle = (func, wait = 1000, type = 1) => {
	let previous = 0;
	let timeout;
	return function() {
		let context = this;
		let args = arguments;
		if (type === 1) {
			let now = Date.now();

			if (now - previous > wait) {
				func.apply(context, args);
				previous = now;
			}
		} else if (type === 2) {
			if (!timeout) {
				timeout = setTimeout(() => {
					timeout = null;
					func.apply(context, args)
				}, wait)
			}
		}
	}
}

二、操作案例

点击事件使用节流的思路(vue2的节流方法)

html:

html 复制代码
 <view class="time">
            <uni-datetime-picker
              v-model="valueTwoTimer"
              type="daterange"
              rangeSeparator="至"
              @change="changeTime"
            />
            <button @click="handleClickLook">搜索</button>
 </view>

js:

javascript 复制代码
import { throttle } from 'lodash'

export default {
  data() {
    return {
      scrollHeight: 0
    }
  },
  mounted() {
    // 监听滚动事件
    window.addEventListener('scroll', this.handleScroll)
  },
  beforeDestroy() {
    // 移除滚动事件监听
    window.removeEventListener('scroll', this.handleScroll)
  },
  methods: {
    // 节流函数
    handleScroll: throttle(function() {
      this.scrollHeight = window.scrollY
      console.log(this.scrollHeight)
      // 执行滚动操作
    }, 500)
    //查看按钮功能
    handleClickLook: throttle(function () {
      this.isFinish = 1;
      this.getInteilEnergyHisDatas(); //1.整体油耗
      this.getfuilOilInfo(); //2.燃油舱
    }, 3000),
  }
}

点击事件使用节流的思路(vue3)

html:

html 复制代码
<el-button
    class="hdtbutton look"
    @click="handleClickLook"
>
  查询
</el-button>

js:

javascript 复制代码
import { getAssetsFile, throttle } from "@/utils";
const handleClickLook = throttle(async () => {
  data.isFinish = 1;
  data.isTips = "加载中...";
  let info = {
    startTime: data.valueTwoTimer[0],
    endTime: data.valueTwoTimer[1],
  };
  //   const resApiData = await getInteilEnergyTotal(info); //接口数据
  const resApiData = false;
  console.log("resApiData>>>", resApiData);
  if (resApiData === false) {
    delayTimer = setTimeout(() => {
      data.isFinish = 2;
      data.isTips = "暂未接入";
    }, data.btnDelay);
    return;
  } else {
    if (resApiData.length && resApiData.length !== 0) {
      data.isFinish = 4;
      data.isTips = "接口数据获取成功";
    } else {
      data.isFinish = 3;
      data.isTips = "暂无数据";
      ElMessage({
        type: "warning",
        message: "暂无数据!",
      });
    }
  }
}, 3000);

其它,

相关推荐
jktantan1 小时前
每个节点 41 字节:把一棵百万节点树拆进 14 个 typed array
前端·javascript·vue.js·算法·typescript
我命由我123451 小时前
访客系统形式(有用户概念、无用户概念)
java·开发语言·前端·javascript·python·产品运营·产品经理
程序员大阳2 小时前
副队长JavaScript教程(65)-详解JSON:轻量级数据交换格式
javascript·json·序列化·反序列化·stringify·parse
paopaokaka_luck4 小时前
基于springboot+vue的益暖微光公益服务平台(DeepSeek公益助手、善款信息追溯、志愿服务积分闭环、ECharts运营分析、活动状态自动流转)
java·前端·javascript·spring boot·mysql·架构·echarts
栀椩4 小时前
Electron 内嵌页面跨域问题(CORS/PNA)解决全记录
前端·javascript·electron
SEO_juper4 小时前
Chrome 扩展一键查看当前页面 SEO 信息:不用切页面,点一下全出来
前端·javascript·chrome
Highcharts.js4 小时前
CSUN 2026|Highcharts无障碍数据与AI分享
javascript·人工智能·数据分析·highcharts·图表开发
系统集成-鹰翔4 小时前
ERP推单数据库怎么备份:SQLite WAL模式下只复制db文件为什么可能漏任务
javascript·数据库·经验分享·后端
小大宇5 小时前
Vue知识点-ElementPlus-05 输入框
前端·javascript·vue.js
外贸GEO优化6 小时前
外贸独立站的可抓取性:JS 渲染、懒加载与无限滚动到底影响什么
开发语言·javascript·ecmascript