首页 > 其他分享 >#yyds干货盘点#按钮点击重复提交问题解决

#yyds干货盘点#按钮点击重复提交问题解决

时间:2022-12-09 23:31:50浏览次数:51  
标签:yyds axios 请求 length 干货 let 按钮 config pending

提交按钮重复点击

这是最常见的问题,重复提交会造成多条数据入库。点击提交给个loading提示过渡,期间按钮不可再次触发就可以。

查询按钮重复点击

如果查询按钮点一下就设置loading,体验其实并不好,但是一直请求,数据不断重新渲染,又会影响性能。 我第一反应是用防抖,如果误触只请求最后一次就好了。

// 防抖
// fn: 回调函数
// delay: 延时时间
export const debounce = (fn, delay = 1000) => {
let timer = null;
return function() {
if (timer !== null) {
clearTimeout(timer);
}
timer = setTimeout(() => {
fn.apply(this, arguments);
}, 1000);
};
};

直到我疯狂点击搜索引擎的搜索按钮,我发现人家用的不是防抖,我陷入沉思,如果我的用户像我一样,那防抖就会让他无法快速看到数据,所以我又觉得应该用节流。

// 节流
export const throttle = (fn, delay = 1000) => {
let old = 0;
return function() {
let now = new Date().valueOf();
if (now - old > delay) {
fn.apply(this, arguments);
old = now;
}
};
};

axios取消重复请求

当多个因素瞬时一起触发某个请求,你会希望只处理最后一次请求,那么可以从axios入手,cancel掉多余的请求

// axios.js

……

const CANCEL_RETRANSMIT = []; // 这里存储需要处理重复请求的url
let s = 1; // 单位秒
let pending = []; // 声明一个数组用于存储每个请求的取消函数和axios标识
let cancelToken = Axios.CancelToken;
let removePending = config => {
pending = pending.filter(i => new Date().getTime() - i.t < s * 1000); // 保留s秒内发的请求
if (
pending.length > 1 &&
pending[pending.length - 2].u === config.url &&
pending[pending.length - 1].t - pending[pending.length - 2].t < s * 1000
) {
pending[pending.length - 2].f(); //执行取消操作
pending.splice(pending.length - 2, 1);
}
};

……

// 请求拦截器内
axios.interceptors.request.use(
async config => {
……
const url = config.url || '';
// 删除重复请求
if (CANCEL_RETRANSMIT.includes(config.url)) {
config.cancelToken = new cancelToken(c => {
// 用请求地址&请求参数拼接的字符串
pending.push({
u: url,
t: new Date().getTime(),
f: c,
});
});
await removePending(config);
}

return config;
},
……
);

这种方式只是让前端减少处理重复请求,但是后端依然会收到多个请求。

标签:yyds,axios,请求,length,干货,let,按钮,config,pending
From: https://blog.51cto.com/u_11365839/5926713

相关文章