防重复提交

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
},
相关推荐
ai产品老杨21 分钟前
实现自动化管理、智能控制、运行服务的智慧能源开源了。
前端·javascript·vue.js·前端框架·ecmascript
飞川撸码25 分钟前
web vue 项目 Docker化部署
前端·vue.js·docker·运维开发
默默无闻的白夜27 分钟前
【Vue】初学Vue(setup函数,数据响应式, 脚手架 )
前端·javascript·vue.js
萌萌哒草头将军32 分钟前
⚡⚡⚡Rstack 家族即将迎来新成员 Rstest🚀🚀🚀
前端·javascript·vue.js
江城开朗的豌豆41 分钟前
Proxy:JavaScript中的'变形金刚',让你的对象为所欲为!
前端·javascript·面试
江城开朗的豌豆1 小时前
JavaScript中的instanceof:你的代码真的认识'自家孩子'吗?
前端·javascript·面试
coding随想1 小时前
深入浅出JavaScript中的ArrayBuffer:二进制数据的“瑞士军刀”
javascript
Watermelo6171 小时前
【前端实战】如何让用户回到上次阅读的位置?
前端·javascript·性能优化·数据分析·哈希算法·哈希·用户体验
Auscy1 小时前
JavaScript 数组学习总结
开发语言·javascript·学习
zhaoyang03013 小时前
css3笔记 (1) 自用
前端·javascript·css·vue.js·笔记·html·css3