防抖 节流 防抖和节流

防抖和节流可以通过使用 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);

其它,

相关推荐
安卓开发者3 分钟前
鸿蒙NEXT Web组件与JavaScript交互:打通原生与前端的桥梁
前端·javascript·harmonyos
fdc201725 分钟前
Avalonia 基础导航实现:从页面切换到响应式交互全指南
开发语言·javascript·ecmascript
小菜花291 小时前
利用H5实现svg图片中各部分监听事件
前端·javascript·svg·object标签
前端小巷子2 小时前
JS 打造「放大镜 + 缩略图」一体组件
前端·javascript·面试
知识分享小能手2 小时前
React学习教程,从入门到精通,React AJAX 语法知识点与案例详解(18)
前端·javascript·vue.js·学习·react.js·ajax·vue3
古夕3 小时前
前端文件下载的三种方式:a标签、Blob、ArrayBuffer
前端·javascript·vue.js
李李记3 小时前
Node.js 打包踩坑?NCC+PKG 从单文件到多平台可执行文件,解决 axios 缺失等 80% 问题
javascript
wow_DG5 小时前
【Vue2 ✨】Vue2 入门之旅 · 进阶篇(九):Vue2 性能优化
javascript·vue.js·性能优化
GDAL6 小时前
Knockout-ES5 入门教程
javascript·knockout
正义的大古6 小时前
OpenLayers数据源集成 -- 章节八:天地图集成详解
开发语言·javascript·ecmascript·openlayers