用闭包封装请求状态和取消机制,配合缓存最新有效响应,是控制高频请求的核心思路:每次新请求生成唯一abortcontroller,自动abort旧请求,成功后更新闭包内缓存,并提供cancel方法。

用闭包封装请求状态和取消机制,配合缓存最新有效响应,是控制高频请求的核心思路。关键在于:每次新请求生成唯一 abortController,并用闭包保存上一次的 controller 和响应数据,新请求触发时自动 abort 旧请求,响应成功后更新缓存。
用闭包维护 abortController 与缓存状态
闭包可将 controller 实例和上一次响应结果封闭在函数作用域内,避免全局污染,也保证多次调用间的状态隔离。典型结构是返回一个带 cancel 方法的请求函数:
- 每次调用都新建 AbortController,保存到闭包变量中
- 发起 fetch 前先调用上一个 controller 的 abort()(若存在)
- 响应成功后,把结果存入闭包内的 cache 变量
- 提供 .cancel() 方法供外部主动终止当前请求
实现一个可取消 + 缓存的请求工厂
下面是一个轻量实用的封装示例,支持手动取消、自动取消旧请求、返回缓存结果:
function createCachedRequest(url, options = {}) {
let lastController = null;
let lastResponse = null;
let lastTimestamp = 0;
return async function request() {
// 主动取消上一次请求
if (lastController) {
lastController.abort();
}
const controller = new AbortController();
lastController = controller;
try {
const res = await fetch(url, {
...options,
signal: controller.signal
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = await res.json();
lastResponse = data;
lastTimestamp = Date.now();
return data;
} catch (err) {
if (err.name === 'AbortError') {
// 被取消,不更新缓存,可选择抛出或静默
throw new Error('Request aborted');
}
throw err;
}
};
}
// 使用方式
const getUser = createCachedRequest('/api/user/123');
getUser().then(console.log); // 发起请求
getUser().then(console.log); // 自动取消前一个,发新请求
按需暴露缓存读取与强制刷新能力
如果需要“优先读缓存、再发请求”的语义(比如防抖场景),可在闭包中增加 getCache() 和 forceRefresh() 方法:
- getCache():直接返回 lastResponse(可加时效判断,如 5 秒内才返回)
- forceRefresh():忽略缓存,强制发起新请求
- request() 默认行为可设为“有缓存且新鲜则返回缓存,否则发请求”
结合防抖或节流进一步控制触发频率
闭包本身不解决高频触发问题,需搭配防抖逻辑使用。例如用 setTimeout 管理请求延迟,同时把定时器 id 和 controller 都封在闭包里:
- 每次触发先 clearTimeout 上一个 timer
- 重设 timer,在 delay 后执行 request()
- cancel() 方法同时 clearTimeout 和 abort()
这样既能抑制频繁调用,又能确保只执行最后一次有效请求,并拿到它的结果。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











