防抖 节流 防抖和节流

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

防抖(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);

其它,

相关推荐
天天扭码14 分钟前
深入解析 JavaScript 中的每一类函数:从语法到对比,全面掌握适用场景
前端·javascript·面试
北上ing1 小时前
同一页面下动态加载内容的两种方式:AJAX与iframe
前端·javascript·ajax
纪元A梦1 小时前
华为OD机试真题——推荐多样性(2025A卷:200分)Java/python/JavaScript/C++/C语言/GO六种最佳实现
java·javascript·c++·python·华为od·go·华为od机试题
小墨宝2 小时前
js 生成pdf 并上传文件
前端·javascript·pdf
www_pp_3 小时前
# 构建词汇表:自然语言处理中的关键步骤
前端·javascript·自然语言处理·easyui
YuShiYue3 小时前
pnpm monoreop 打包时 node_modules 内部包 typescript 不能推导出类型报错
javascript·vue.js·typescript·pnpm
天天扭码4 小时前
总所周知,JavaScript中有很多函数定义方式,如何“因地制宜”?(ˉ﹃ˉ)
前端·javascript·面试
一个专注写代码的程序媛4 小时前
为什么vue的key值,不用index?
前端·javascript·vue.js
장숙혜4 小时前
ElementUi的Dropdown下拉菜单的详细介绍及使用
前端·javascript·vue.js
火柴盒zhang4 小时前
websheet之 编辑器
开发语言·前端·javascript·编辑器·spreadsheet·websheet