防重复提交

1. Debouncing(防抖)

原理

  • 防抖是在一段时间内只执行最后一次请求。如果用户在设定时间内多次触发操作,只有最后一次操作会被执行,前面的操作会被取消。

优点

  • 避免短时间内重复请求,只执行最后一次操作。
  • 对用户频繁操作(如输入搜索关键字)非常有效。

缺点

  • 如果用户需要立即得到反馈,可能会产生延迟,因为必须等待设定的防抖时间过去才会发起请求。
  • 适合输入类场景,但不适合所有场景,比如按钮点击的请求场景。
js 复制代码
function debounce(fn, delay) {
  let timeout;
  return function (...args) {
    clearTimeout(timeout);
    timeout = setTimeout(() => fn.apply(this, args), delay);
  };
}

// 使用示例
const submitForm = debounce(function() {
  // 网络请求逻辑
}, 500);

2. Throttling(节流)

原理

  • 节流是在规定的时间间隔内只允许发起一次请求。无论用户在这段时间内多次触发操作,都只有一次操作会被执行,后续操作会被忽略。

优点

  • 能有效控制请求频率,避免过度请求。
  • 对于需要控制请求频率的场景(如滚动加载)非常适合。

缺点

  • 用户频繁操作时,某些操作可能被忽略,无法立即响应用户的每次操作。
  • 不适用于要求立即响应用户每次操作的场景。
js 复制代码
function throttle(fn, interval) {
  let lastTime = 0;
  return function (...args) {
    const now = Date.now();
    if (now - lastTime >= interval) {
      lastTime = now;
      fn.apply(this, args);
    }
  };
}

// 使用示例
const submitForm = throttle(function() {
  // 网络请求逻辑
}, 1000);

3. Loading 状态限制

原理

  • 利用 loading 状态变量在请求发起时设置为 true,请求完成后重置为 false。当 loadingtrue 时,阻止后续请求。

优点

  • 简单易实现,适用于需要确保单次操作期间不会重复触发请求的场景。
  • 用户点击操作后会立即得到反馈,提升用户体验。

缺点

  • 只适用于阻止在请求未完成之前的重复请求,不能限制在短时间内连续发起多次不同请求。
js 复制代码
data() {
  return {
    loading: false,
  };
},
methods: {
  submitForm() {
    if (this.loading) return;
    this.loading = true;

    uni.request({
      url: 'https://example.com/api/submit',
      method: 'POST',
      data: {},
    }).then(response => {
      // 处理响应
    }).finally(() => {
      this.loading = false;
    });
  }
}

总结

  • Debouncing 适合用户输入类操作,防止频繁请求,只执行最后一次操作。
  • Throttling 适合需要限制操作频率的场景,能有效控制请求频率。
  • Loading 状态限制 适合需要确保在请求完成前不会重复请求的场景,简单易用
js 复制代码
// //防抖
function debounce(fn, date) {
  let timer  //声明接收定时器的变量
  return function (...arg) {  // 获取参数
    timer && clearTimeout(timer)  // 清空定时器
    timer = setTimeout(() => {  //  生成新的定时器
      //因为箭头函数里的this指向上层作用域的this,所以这里可以直接用this,不需要声明其他的变量来接收
      fn.apply(this, arg) // fn()
    }, date)
  }
}
//--------------------------------
// 节流
function debounce(fn, data) {
  let timer = +new Date()  // 声明初始时间
  return function (...arg) { // 获取参数
    let newTimer = +new Date()  // 获取触发事件的时间
    if (newTimer - timer >= data) {  // 时间判断,是否满足条件
      fn.apply(this, arg)  // 调用需要执行的函数,修改this值,并且传入参数
      timer = +new Date() // 重置初始时间
    }
  }
}

// 状态锁
lock: false, // 防止多次点击

if (!this.lock) {
    this.lock = true
    uni.navigateTo({
        url: '/qualityInspection/pages/areaDetails/index',
        success: () => {
            this.lock = false;
        },
        fail: () => {
            this.lock = false;
        }
    })
}

// uniapp button loading
<button type="default" @click="payment" :loading="loading" :disabled="disabled">立即支付</button>

// 执行支付
async payment() {
    let params = {
        oderType: "order",
        openId: this.openId,
        platform: this.platform,
        pay_type: this.pay_type,
        orderId: this.id
    }
    uni.showLoading({
        title: '请稍等'
    })
    this.loading = true
    this.disabled = true
    let res = await orderPay(params);
    uni.hideLoading()
    this.loading = false
    this.disabled = false
},
相关推荐
毕设源码-朱学姐5 小时前
【开题答辩全过程】以 工厂能耗分析平台的设计与实现为例,包含答辩的问题和答案
java·vue.js
老前端的功夫6 小时前
Vue 3 性能深度解析:从架构革新到运行时的全面优化
javascript·vue.js·架构
前端 贾公子7 小时前
vue移动端适配方案 === postcss-px-to-viewport
前端·javascript·html
GISer_Jing8 小时前
AI营销增长:4大核心能力+前端落地指南
前端·javascript·人工智能
前端小端长9 小时前
Vue 中 keep-alive 组件的原理与实践详解
前端·vue.js·spring
m0_471199639 小时前
【场景】前端怎么解决离线收银、数据同步异常等场景问题
前端·javascript
小胖霞10 小时前
企业级全栈项目(14) winston记录所有日志
vue.js·前端框架·node.js
栀秋66610 小时前
“无重复字符的最长子串”:从O(n²)哈希优化到滑动窗口封神,再到DP降维打击!
前端·javascript·算法
xhxxx10 小时前
不用 Set,只用两个布尔值:如何用标志位将矩阵置零的空间复杂度压到 O(1)
javascript·算法·面试