防重复请求需“阻断源头+控制状态+管理请求生命周期”三层协同:按钮禁用与超时恢复、函数防抖、请求去重、事件监听净化缺一不可。

核心思路是“阻断源头 + 控制状态 + 管理请求生命周期”,不是只靠禁用按钮,而是多层配合,才能真正防住暴力点击、快速切换、事件重复绑定等真实场景下的重复请求。
按钮状态控制:最直接的用户感知层
点击即禁用,响应后恢复,配合视觉反馈(如文字变“提交中”),让用户明确知道操作已被接收:
- 使用 prop("disabled", true) 而非 attr,确保 DOM 属性与实际状态一致
- 务必在 complete 回调中恢复按钮(不是仅 success 或 error),避免请求异常时按钮永久锁定
- 设置合理超时(如 4000ms),超时后自动恢复按钮并提示“请求超时,请重试”
函数防抖:应对高频点击的逻辑层
当用户连续猛点按钮(比如 200ms 内点 5 下),只让最后一次点击触发请求,前几次被自动忽略:
- 封装一个带 clearTimeout 的闭包函数,每次点击重置定时器
- 延迟时间建议设为 300–500ms,太短起不到作用,太长影响响应感
- 适用于表单提交、搜索触发、分页跳转等“意图明确、无需多次执行”的操作
请求级去重:同一接口并发拦截
针对相同 URL(或加参数哈希)的请求,在上一个还没返回前,新请求直接忽略或取消旧请求:
立即学习“Java免费学习笔记(深入)”;
- 维护一个对象或 Map,key 是请求标识(如 url + JSON.stringify(params)),value 是当前请求的 cancel token 或 jqXHR 实例
- 发请求前先查是否存在 pending 请求:存在则 abort()(jQuery)或 source.cancel()(axios)
- 特别适合 tab 切换、下拉刷新、搜索联想等易触发重复请求的交互
事件监听净化:防止 submitLog 被重复绑定
很多重复请求其实不是用户点太快,而是 JavaScript 把同一个事件监听器绑了多次:
- 用 addEventListener 时,添加前先 removeEventListener 同名函数,或使用 { once: true } 选项
- jQuery 绑定推荐用 off().on() 替代反复 on(),避免监听器堆积
- 检查是否在初始化、路由切换、模态框打开等时机重复执行了绑定逻辑


















