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
。当loading
为true
时,阻止后续请求。
优点:
- 简单易实现,适用于需要确保单次操作期间不会重复触发请求的场景。
- 用户点击操作后会立即得到反馈,提升用户体验。
缺点:
- 只适用于阻止在请求未完成之前的重复请求,不能限制在短时间内连续发起多次不同请求。
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
},