小程序的防抖节流怎么写?

本文详细介绍了JavaScript中的函数防抖(debounce)和函数节流(throttle)的概念,提供了相应的代码封装示例,并展示了在实际应用场景中如何使用这两种优化技巧,如输入框输入监听和按钮点击事件处理。通过防抖和节流,可以有效地提高性能,避免频繁调用函数导致的资源浪费。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.概念

函数防抖(debounce)

函数防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。

简单的说,当一个动作连续触发,则只执行最后一次

如果有人进电梯(触发事件),那电梯将在10秒钟后出发(执行事件监听器),这时如果又有人进电梯了(在10秒内再次触发该事件),我们又得等10秒再出发(重新计时)

函数节流(throttle)

限制一个函数在一定时间内只能执行一次。

保证如果电梯第一个人进来后,10秒后准时运送一次,这个时间从第一个人上电梯开始计时,不等待,如果没有人,则不运行

2. 代码封装

函数防抖(debounce)

/**
 *
 * @param {*} cb 回调函数
 * @param {*} delay 延时时间
 */
const debounce = (cb, delay = 1000) => {
  let timer = null;
  return function() {
    if (timer) {
      clearTimeout(timer);
    }
    timer = setTimeout(() => {
      cb.apply(this, arguments);
    }, delay);
  };
};

函数节流(throttle)

/**
 *
 * @param {*} cb 回调函数
 * @param {*} wait 等待时间
 */
const throttle = (cb, delay = 1000) => {
  //距离上一次的执行时间
  let lastTime = 0;
  return function() {
    let _this = this;
    let _arguments = arguments;
    let now = new Date().getTime();
    //如果距离上一次执行超过了delay才能再次执行
    if (now - lastTime > delay) {
      cb.apply(_this, _arguments);
      lastTime = now;
    }
  };
};

3. 使用

mine.axml

<view class="root_container">
  
  <input placeholder="Input" onInput="inputHandle" />

  <button size="default" type="primary" catchTap='clickHandle'>Button</button>
</view>

mine.js

import { debounce, throttle } from "/utils/index.js";

  // 节流使用
  clickHandle: throttle(function(...args) {
    console.log("throttle", args);
    console.log("throttle", this);
  }, 2000),

  // 防抖使用
  inputHandle: debounce(function(...args) {
    console.log("debounce args", args);
    console.log("debounce this", this);
  }, 1000),
<think>好的,我现在需要解决用户在微信小程序中如何对提交按钮实现防抖节流的问题。首先,我得回忆一下防抖节流的概念,以及它们在小程序中的应用场景。 根据用户提供的引用[1]和[2],防抖(debounce)是延迟函数执行,比如在输入框输入时,等待用户停止输入后再执行搜索。而节流(throttle)是限制函数在一定时间内只执行一次,比如防止按钮重复点击。用户的问题是关于提交按钮的,所以可能需要根据具体情况选择使用防抖还是节流。 接下来,我需要考虑在小程序中如何具体实现这两个功能。通常,防抖节流可以通过封装函数来实现。引用[1]中提供了一个节流函数的例子,使用时间戳来控制执行频率。而防抖函数可能需要使用定时器,在延迟时间内如果有新触发就重置定时器。 用户的问题可能涉及如何在小程序的页面中应用这些函数。例如,在按钮的点击事件处理函数中使用防抖节流。需要注意的是,小程序中的函数调用方式,比如使用this.setData或者调用API接口,可能需要绑定正确的上下文。 另外,还需要考虑防抖节流的参数设置,比如防抖的延迟时间或节流的间隔时间。不同的场景可能需要不同的时间设置,比如提交按钮如果涉及到网络请求,可能需要较短的节流间隔,防止用户频繁点击导致多次提交。 然后,我需要验证这些方法的正确性。例如,节流函数是否真的在间隔时间内只执行一次,防抖函数是否在连续点击后只执行最后一次。可能需要通过代码示例和测试来确认。 最后,要总结最佳实践,明确防抖节流的适用场景,并给出代码实现的建议。同时,可能需要提醒用户注意函数的封装和this指向的问题,确保在小程序中正确使用。</think>### 微信小程序提交按钮防抖节流实践 #### 一、防抖节流的区别 - **防抖(Debounce)**:延迟执行,若在等待时间内重复触发,则重新计时。适用于避免连续点击导致多次请求的场景,例如搜索框联想词请求[^2]。 - **节流(Throttle)**:固定时间内只执行一次,无论触发频率多高。适用于限制高频操作(如滚动事件、按钮点击)的场景。 #### 二、提交按钮的实现方案 1. **防抖适用场景** 当需要确保用户最后一次操作触发请求(例如提交表单后需等待用户确认信息完毕)。 2. **节流适用场景** 当需要限制用户点击频率(例如防止用户1秒内多次点击提交导致重复订单)。 --- #### 三、代码实现 ##### 1. 防抖函数封装 ```javascript function debounce(fn, delay) { let timer = null; return function (...args) { clearTimeout(timer); timer = setTimeout(() => { fn.apply(this, args); // 延迟 delay 毫秒后执行 }, delay); }; } ``` ##### 2. 节流函数封装(优化版) ```javascript function throttle(fn, interval) { let lastCall = 0; return function (...args) { const now = Date.now(); if (now - lastCall >= interval) { lastCall = now; fn.apply(this, args); // 确保间隔时间内只执行一次 } }; } ``` --- #### 四、在小程序中的具体应用 **页面JS文件** ```javascript // 引入工具函数 import { debounce, throttle } from '../../utils/util.js'; Page({ // 防抖提交(延迟500ms执行) handleDebounceSubmit: debounce(function() { this.submitForm(); // 实际提交逻辑 }, 500), // 节流提交(1秒内仅执行一次) handleThrottleSubmit: throttle(function() { this.submitForm(); }, 1000), submitForm() { wx.request({ url: 'https://api.example.com/submit', method: 'POST', success: () => { wx.showToast({ title: '提交成功' }); } }); } }); ``` **WXML文件** ```html <button bindtap="handleDebounceSubmit">防抖提交</button> <button bindtap="handleThrottleSubmit">节流提交</button> ``` --- #### 五、最佳实践建议 1. **参数选择** - 防抖延迟建议:300-800ms(平衡响应速度和误触) - 节流间隔建议:1000ms(适用于支付类关键操作) 2. **注意点** - 使用`apply(this, args)`保持函数上下文,避免小程序页面方法调用失败 - 网络请求建议配合加载状态提示(如`wx.showLoading`) - 对于表单验证,应在防抖/节流前先校验数据合法性 3. **扩展优化** ```javascript // 增强版节流:最后一次点击强制执行 function throttle(fn, interval) { let lastCall = 0, timer = null; return function (...args) { const now = Date.now(); if (now - lastCall >= interval) { lastCall = now; fn.apply(this, args); } else { clearTimeout(timer); timer = setTimeout(() => { fn.apply(this, args); }, interval); } }; } ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值