← 中文资源

简体中文版本

通过中止信号实现最新请求优先

新请求启动时中止上一个进行中的请求,并用序号检查丢弃过期结果,避免慢响应覆盖新数据。

阅读英文原文

功能说明

搜索框和筛选器会连续触发请求,较慢的旧响应可能覆盖新结果。该控制器为每次请求生成序号,启动新请求时中止旧请求,并在返回时检查序号,只有最新结果会被采用。它适合搜索建议、列表刷新和地图视野变化等高频请求场景。

关键代码

run 创建 AbortController,调用 begin 获取 isCurrent 闭包,并中止上一个控制器。任务收到 signal,完成后用 isCurrent 判断是否仍为最新;若已过期返回 undefined。中止导致的异常被吞掉,其他错误继续抛出。abort 方法可以主动取消当前任务。

const isCurrent = this.begin();
if (this.active) this.active.abort();
this.active = controller;
const result = await task(controller.signal);
return isCurrent() ? result : undefined;

使用注意

任务必须把 signal 传给 fetch 等可中止 API,否则旧任务仍会消耗资源。返回 undefined 表示结果已过期,调用方应忽略。连续调用时只有最后一个任务的结果有效。该类不负责缓存,也不合并相同请求。abort 后没有新请求时,活动状态会被清理。

验证方式

断言快速启动两个任务时,先完成的慢任务不会返回结果。新任务会触发旧信号 abort。非中止错误正常抛出。任务完成后 active 被清理。调用 abort 后,进行中的任务返回 undefined。不同任务的结果与序号互不干扰。