技术解读
项目背景与痛点
前端的数据请求在过去十年里经历了三次抽象:从 XMLHttpRequest 到 fetch,再到 axios 这层「请求库」,最后是 TanStack Query / SWR 这层「请求状态管理」。但真正做业务的人会发现,问题并没有解决,只是被重新分配了。
fetch 只给你一个 Promise,剩下的一切都要你自己写:loading 状态、错误重试、请求去重、缓存失效、取消、超时、SSR 序列化,以及最麻烦的——实时数据与请求数据的缝合。WebSocket 推过来一条消息,你得手动去 queryClient.setQueryData 里打补丁,改完还要自己去触发重渲染。
hyper-fetch 的切入点是:把「一次请求」从一个函数调用,提升为一个可描述、可复用、可被调度器管理的命令对象。它的自我定位是 “Fetching and realtime data exchange framework”,后半句才是重点——它不只想做请求层,还想吃掉实时数据这半块拼图。
核心技术揭秘
从架构上看,hyper-fetch 走的是一套很接近后端「中间件 + 调度器」的思路,而非 React 生态里常见的 Hook 优先方案。
最底层是 Adapter 适配层,把 fetch、axios、GraphQL 抽象成统一接口。这意味着网络层是可替换的,迁移成本极低,也方便在测试环境中塞入 mock adapter。往上一层是 Dispatcher(调度器),它是整个框架的大脑,串起缓存、队列、重试、生命周期钩子。再往上才是 React / Vue / Svelte 的 hooks 绑定。
请求本身被定义为 Request 实例(命令模式),携带 url、method、params、响应类型等元信息,并且是纯描述性的——同一个 Request 对象可以在不同组件、不同时间被重复 dispatch,行为完全一致。这正是它和「在组件里直接写 axios.get」的本质区别。类型系统在这里发挥了大作用:响应类型、错误类型、query params 类型都可以从 Request 定义中反向推导,而不需要你手写泛型。
真正的杀手锏是右侧那条 PubSub 支路。hyper-fetch 内置了消息总线,并且提供了与 WebSocket / Socket.IO 的对接能力。它的做法是:把服务端推送的消息按 topic / key 映射到已有的请求实例上,命中后直接更新缓存并广播,订阅了该请求的组件自动拿到新数据。也就是说,一次 HTTP 请求和一条 WebSocket 推送,在数据层被归一到同一个缓存实体,组件侧完全不需要感知数据来源。这是它跟 SWR 类库最大的分野。
Queue 层负责并发控制和重试退避,缓存层支持内存、LocalStorage、IndexedDB 多种后端,可以组合出 stale-while-revalidate 这类策略。整条链路上开放了大量生命周期钩子(onRequest / onResponse / onError / onSuccess),允许你在不改动业务代码的前提下插入鉴权、日志、埋点。
功能亮点与差异
第一,网络库无关性。 TanStack Query 基本绑死 fetch 语义,而 hyper-fetch 通过 adapter 把 axios、GraphQL 都纳进来,对存量项目友好——你不需要为了引入它而重写网络层。
第二,请求即命令。 请求定义可以单独抽成文件、被多个页面引用、被单元测试直接实例化,这在中大型项目里对「请求契约」的收敛非常有价值。
第三,实时与请求的统一。 这是差异化最强的一点。大部分竞品把 WebSocket 当成另一套体系,hyper-fetch 把它吸收进缓存模型。
第四,框架无关的核心。 Dispatcher、Cache、Queue 都在框架层之外,React 只是薄薄一层绑定,理论上可以移植到任何 UI 框架。
应用场景与落地建议
它最适合两类场景:实时性要求高的中后台(监控大盘、协作编辑、交易行情),以及请求契约复杂、多团队共享接口层的大型前端。
生产落地时有几个坑要提前避开:
- Cache key 设计要一次性规划好,否则 PubSub 的 topic 映射会变成一团乱麻,这是最容易踩的雷;
- 不要在早期过度抽象。命令模式带来的收益随项目规模线性增长,小项目里它只是额外的样板代码;
- 注意请求取消与缓存生命周期。单页应用里长驻的缓存实体如果没人清理,内存会缓慢膨胀;
- 调试链路变长。请求经过 Dispatcher、Queue、Adapter 三层,出错时要有意识地分层定位,别只盯着 network 面板;
- SSR 场景要验证,命令对象可序列化是优势,但缓存和 PubSub 在服务端的行为需要实测。
综合评价
优点:架构分层清晰,adapter + dispatcher + cache + pubsub 的组合拳打得很有章法;请求契约与实时数据的统一是真正的设计洞察,不是 API 堆砌;类型推导扎实,命令模式让请求可测试、可复用。
缺点:学习曲线明显高于 SWR 这类「三行上手」的库,心智模型需要时间建立;社区体量和生态远不及 TanStack Query,出问题时可参考的案例少;文档组织偏零散,很多能力要靠翻源码和类型定义才能发现;抽象层数多,出 bug 时定位成本更高。
一句话结论:如果你只是想要一个带缓存的请求 Hook,它是杀鸡用牛刀;但如果你正在为「HTTP 请求和 WebSocket 推送各管一摊」而头疼,hyper-fetch 是目前少数真正想过这件事的框架,值得花一个下午读源码。
评论