背景

每个页面各写一遍 fetch,最终会产生不同的超时、错误和 JSON 解析行为。统一客户端是把网络不确定性收敛到一个边界。

核心判断

  1. 统一取消、超时、HTTP 状态与响应解析。
  2. 领域接口接受运行时解码器,不靠 request 断言服务端数据。
  3. 区分网络失败、HTTP 拒绝和响应契约错误,供界面选择恢复策略。

最小示例

下面保留核心逻辑;业务类型、调用入口和环境配置按项目补齐。

async function request<T>(
  input: RequestInfo,
  decode: (value: unknown) => T,
): Promise<T> {
  const response = await fetch(input, {
    signal: AbortSignal.timeout(5000),
  });
  if (!response.ok) throw new ApiError(response.status);
  const value: unknown = await response.json();
  return decode(value);
}

边界与误区

AbortSignal.timeout 需要目标运行环境支持。204 无响应体、非 JSON 错误页和调用方取消也要处理;示例适用于约定 JSON 正文的接口。

验证方式

用 mock server 覆盖慢响应、401、500、畸形 JSON 和错误字段。检查同一错误类型在不同页面的提示与重试策略保持一致。

小结

客户端统一处理超时、取消、解析和错误,领域层只暴露稳定的方法和错误分类。