防抖函数通过重置计时器确保只执行最后一次触发,但不自动取消已发出的网络请求;需结合abortcontroller或canceltoken手动终止前序请求,才能避免并发。

防抖函数本身不处理并发请求,它会取消前一次未完成的请求,只执行最后一次触发的操作。
防抖的核心逻辑是“重置计时器”
每次触发事件时,防抖函数会清除之前的定时器,并重新设置一个新的延迟执行任务。这意味着在连续触发过程中,只有最后一次触发后的延迟任务会被执行,中间所有未到时间的调用都会被丢弃。
- 适合场景:搜索框输入联想、窗口大小调整(resize)、按钮防重复点击(需配合请求取消)
- 关键点:防抖不等待请求完成,只控制函数执行时机;若上一个请求尚未返回,它不会自动取消该请求,除非你手动实现取消逻辑
要真正避免并发请求,需结合 AbortController 或 cancelToken
原生防抖只控制函数是否执行,不干预已发出但未响应的网络请求。若想确保同一时刻只有一个请求在进行,必须在发起请求前主动终止前一个请求。
- 使用 AbortController:每次新请求前调用
abort(),并在 fetch 中传入signal - React 中可借助 useRef 缓存 controller 实例,避免闭包捕获旧值
- Axios 用户可用 CancelToken(v0.22+ 推荐用 AbortController)
一个带请求取消的防抖示例
以下是一个实际可用的封装思路:
- 定义一个 ref 存储当前请求的
AbortController - 每次防抖触发时,先调用
controller.abort()(忽略报错),再新建 controller 并发起请求 - fetch 的
signal选项绑定新 controller 的 signal - 这样即使用户快速输入多次,也只会有一个请求真正发出去,其余都被取消
注意和节流、竞态处理的区别
节流限制单位时间内最多执行一次,但不取消中间请求;而防抖+取消才是解决“最后有效请求”的典型方案。真正的“竞态处理”还可能涉及 Promise.race、useSWR 的 keepPreviousData 等更高阶策略,但基础防抖本身不包含这些能力。











