微信小程序节流与防抖问题

函数防抖: 英文 debounce 有防反跳的意思,大致就是指防止重复触发。

那么,函数防抖,真正的含义是:延迟函数执行即不管debounce函数触发了多久,只在最后一次触发debounce函数时,才定义setTimeout,到达间隔时间再执行 需要防抖的函数。

用处:多用于 input 框 输入时,显示匹配的输入内容的情况。

函数节流: 英文 throttle 有节流阀的意思。大致意思也是 节约触发的频率

那么,函数节流,真正的含义是:单位时间n秒内,第一次触发函数并执行,以后 n秒内不管触发多少次,都不执行。直到下一个单位时间n秒,第一次触发函数并执行,这个n秒内不管函数多少次都不执行

用处:多用于页面scroll滚动,或者窗口resize,或者防止按钮重复点击等情况

其实如果只根据 控制函数触发的频率是不好区分这两个概念的。我认为两个函数都能达到防止重复触发的功能。但是函数防抖是 n秒后延迟执行;而函数节流是立马执行,n秒后再立马执行。

在小程序中,函数防抖、函数节流的使用方式:

一般都会把这两种方法封装在公用的 js 中:

/*函数节流*/
function throttle(fn, interval) {
  var enterTime = 0;//触发的时间
  var gapTime = interval || 300 ;//间隔时间,如果interval不传,则默认300ms
  return function() {
    var context = this;
    var backTime = new Date();//第一次函数return即触发的时间
    if (backTime - enterTime > gapTime) {
      fn.call(context,arguments);
      enterTime = backTime;//赋值给第一次触发的时间,这样就保存了第二次触发的时间
    }
  };
}
 
/*函数防抖*/
function debounce(fn, interval) {
  var timer;
  var gapTime = interval || 1000;//间隔时间,如果interval不传,则默认1000ms
  return function() {
    clearTimeout(timer);
    var context = this;
    var args = arguments;//保存此处的arguments,因为setTimeout是全局的,arguments不是防抖函数需要的。
    timer = setTimeout(function() {
      fn.call(context,args);
    }, gapTime);
  };
}
 
export default {
  throttle,
  debounce
};

使用

import tool from "../../static/js/tool.js";
Page({
   data:{
    win_scrollTop:0
   },
   onPageScroll: tool.throttle(function(msg){
      this.setData({
        win_scrollTop: msg[0].scrollTop
      });
   }),
   gotoUnlock: tool.debounce(function() {
      this.saveUserInfo();
   }),
   saveUserInfo:function(){
      console.log(111)
   }
})

登录时可采取以下办法:

点击登陆时,将button的disable属性置为true,成功或失败都置为false 

摘抄自:微信小程序之使用函数防抖与函数节流

<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、付费专栏及课程。

余额充值