客户端与注册
创建 Fetcher 以共享 URL、请求头、超时和拦截器策略。请求默认调用运行时全局 fetch,fetch 选项可替换它;客户端不管理连接池,也不需要 destroy()。
构造与默认值
new Fetcher(options?: FetcherOptions) 接受下列选项。传入选项对象时必须包含 baseURL;省略整个对象时使用 DEFAULT_OPTIONS。
| 选项 | 默认值 | 契约 |
|---|---|---|
baseURL: string | '' | 由可修改的 urlBuilder 使用;相对 URL 仍要求运行时支持。 |
headers?: RequestHeaders | {} | 默认没有 Content-Type,由正文拦截器按正文设置;客户端保存传入对象的副本;每个请求防御性复制并按大小写不敏感规则合并。 |
timeout?: number | undefined | 单位毫秒;未配置不启用定时器。请求级 0 禁用继承的超时。 |
urlTemplateStyle? | UrlTemplateStyle.UriTemplate | 默认 {id};Express 使用 :id。 |
interceptors? | 新建 InterceptorManager | 传入管理器时直接使用,也可在客户端间共享。 |
validateStatus? | 200 <= status < 300 | 仅在创建默认管理器时使用。 |
fetch?: FetchImplementation(类型) | 全局 fetch,调用时读取 | 发送请求所用的 fetch,适用于自带实现的运行时或框架(Tauri、埋点)以及测试。超时和信号仍然生效。与 validateStatus 相同,仅在创建默认管理器时使用。 |
可修改 urlBuilder、headers、timeout,影响后续请求。interceptors 属性只读,但其中的注册表可修改。每个客户端持有自己的请求头副本,修改 client.headers 只影响该客户端;修改导出的 DEFAULT_OPTIONS.headers 仍会影响之后创建的所有客户端,应改用请求级头。
选择调用入口
| 方法 | 输入 | 不指定提取器时的结果 |
|---|---|---|
resolveExchange(request, options?) | FetchRequest、RequestOptions | 同步返回 FetchExchange,不执行 HTTP I/O。 |
exchange(request, options?) | 同上 | 拦截器管线结束后的 Promise<FetchExchange>,不提取正文。 |
request<R = FetchExchange>(request, options?) | 同上 | 经提取器得到 Promise<R>,默认返回 exchange。 |
fetch<R = Response>(url, request = {}, options?) | FetchRequestInit | Promise<R>,默认原生 Response。 |
get、head、options、trace | URL、不含 method/body 的请求、选项 | Promise<R = Response>,辅助方法固定 HTTP 方法。 |
post、put、patch、delete | URL、不含 method 的请求、选项 | 同上,可传 body。 |
DEFAULT_REQUEST_OPTIONS 选择 ResultExtractors.Exchange;DEFAULT_FETCH_OPTIONS 选择 ResultExtractors.Response。只写 get<User>() 不会解析 JSON,必须选择提取器或调用 response.json<User>()。原生 Fetch 可能拒绝 TRACE 等方法。参阅结果提取和错误处理。
命名客户端
new NamedFetcher(name, options?) 继承 Fetcher,并立即注册到单例 fetcherRegistrar;它保存在 globalThis 上,同一进程中的第二份包副本(ESM 与 CommonJS 构建,或两个版本)共享它。导出的 fetcher 是默认命名实例,DEFAULT_FETCHER_NAME = 'default';第二份副本复用已注册的默认实例,而不替换它。同名注册替换原有客户端。
FetcherRegistrar.register(name, client): void、unregister(name): boolean、get(name): Fetcher | undefined 管理条目。缺失时 requiredGet(name) 与 default getter 抛出 Error。设置 default 会注册到 'default';fetchers 返回新的 Map,值仍是相同客户端。注销不会中止正在进行的请求。
getFetcher(fetcher?, defaultFetcher?) 接受实例、注册名或空值。字符串视为名称,必须已注册;其他值直接作为 fetcher 使用(不做 instanceof 检查,另一份包副本创建的 fetcher 也可用);假值优先选择传入的后备客户端,再选择全局默认实例。FetcherCapable 声明此可选字段,NamedCapable 声明 name,FetcherConfigurer.applyTo(fetcher): void 是扩展配置器使用的结构契约。
完整示例
import {
Fetcher,
NamedFetcher,
fetcherRegistrar,
getFetcher,
} from '@ahoo-wang/fetcher';
const local = new Fetcher({
baseURL: 'https://api.example.com',
timeout: 3000,
});
const named = new NamedFetcher('reports', {
baseURL: 'https://reports.example.com',
});
console.assert(getFetcher('reports') === named);
const exchange = local.resolveExchange({ url: '/users/1' });
console.assert(exchange.request.timeout === 3000);
fetcherRegistrar.unregister('reports');公开符号与源码
| 符号 | 实现 |
|---|---|
FetcherOptions | fetcher.ts:57 |
DEFAULT_OPTIONS | fetcher.ts:105 |
RequestOptions | requestOptions.ts:21 |
DEFAULT_REQUEST_OPTIONS | requestOptions.ts:25 |
DEFAULT_FETCH_OPTIONS | requestOptions.ts:30 |
Fetcher | fetcher.ts:129 |
FetcherCapable | fetcherCapable.ts:22 |
getFetcher | fetcherCapable.ts:37 |
DEFAULT_FETCHER_NAME | fetcherRegistrar.ts:19 |
FetcherRegistrar | fetcherRegistrar.ts:41 |
fetcherRegistrar | fetcherRegistrar.ts:172 |
NamedFetcher | namedFetcher.ts:38 |
fetcher | namedFetcher.ts:94 |
NamedCapable | types.ts:141 |
FetcherConfigurer | fetcherConfigurer.ts:39 |
