封装自定义 httpclient 时,用 ref 管理请求计数器,在 request 拦截器中 +1、response/error 拦截器中 -1,isloading 由计数器是否大于 0 派生,确保状态一致且自动同步,并支持 showloading 配置灵活控制。

封装自定义 HttpClient 类时,要让全局 loading 状态与请求计数器联动,核心是统一拦截请求发起和响应完成的时机,并用一个可响应的状态变量(如 ref 或 signal)跟踪当前活跃请求数量。loading 状态由该数量是否为 0 决定。
用 ref 管理请求计数器
在自定义 client 实例中维护一个 ref(如 Vue 的 ref(0) 或 React 的 useRef(0)),每次请求开始前 +1,结束(无论成功或失败)后 -1。注意必须确保成对调用,避免计数失衡。
- 推荐在拦截器(interceptor)中统一处理:request 拦截器里递增,response/error 拦截器里递减
- 若使用 Axios,需同时注册
useRequestInterceptor和useResponseInterceptor(或原生的interceptors.request.use/interceptors.response.use) - 避免在业务代码里手动增减——否则易遗漏、难维护
将计数器映射为 loading 状态
loading 状态不是独立变量,而是对计数器的派生值:当计数 > 0 时视为 loading 中。这样天然保证状态一致性,无需额外同步逻辑。
- Vue 示例:
const isLoading = computed(() => requestCount.value > 0) - React 示例:
const isLoading = requestCount.current > 0(配合 useEffect 监听变化触发重渲染) - 关键点:组件只订阅这个派生状态,不直接操作 loading 变量
处理并发与异常场景
真实场景中需防止单个请求失败导致计数卡死,或并发请求因拦截器执行顺序错乱引发负数。
- 在 response 拦截器中,无论
status === 200还是网络错误、超时、取消,都必须执行count-- - 对 cancel 请求(如 AbortController),需在 request 拦截器中注册 abort 事件,在 abort 时主动减一(部分库需手动处理)
- 可加防护:减一前判断
count > 0,避免意外负数(说明有漏增,应查拦截器注册逻辑)
暴露便捷的请求方法并保持透明性
自定义 client 应保留原始 HttpClient 的语义(如 get/post/put),内部自动注入计数逻辑,业务层无感知。
- 例如:
myHttp.get('/api/user')自动触发计数+1,响应后-1 - 如需临时跳过 loading(如轮询、静默刷新),可提供选项参数:
myHttp.get('/api/status', { showLoading: false }) - 所有配置(baseURL、headers、timeout)仍可透传,不破坏原有使用习惯










