Skip to content

Exchange 与结果提取

结果提取器决定运行时返回值,与 request<R>get<R> 的 TypeScript 泛型独立。在 RequestOptions.resultExtractor 中选择提取器。

选择提取器

ResultExtractor<R>(exchange: FetchExchange) => R | Promise<R>ResultExtractorCapable 声明其可选字段。ResultExtractors 中的属性直接对应下列导出函数:

属性 / 导出函数Promise 解析后的值正文读取
Exchange / ExchangeResultExtractor同一个 FetchExchange不读取
Response / ResponseResultExtractorexchange.requiredResponse不读取
Json / JsonResultExtractor已解析 JSON(anyResponse.json()
Text / TextResultExtractorstringResponse.text()
Blob / BlobResultExtractorBlobResponse.blob()
ArrayBuffer / ArrayBufferResultExtractorArrayBufferResponse.arrayBuffer()
Bytes / BytesResultExtractorUint8Array<ArrayBuffer>Response.bytes(),要求运行时支持。

JSON 类型仅为编译期约定,不提供运行时校验。包对 Response.json<T = any>(): Promise<T> 的扩展只影响类型。204 空响应仍会 JSON 解析失败;空正文应选择 Response 或自定义提取器。

FetchExchange

new FetchExchange(init: FetchExchangeInit) 要求 fetcherrequest,可选 resultExtractorresponseerrorattributesAttributesCapable.attributes 接受记录或 Map,构造时把条目复制到新 Map。提取器默认 Exchange;请求与响应均保留引用,不复制。

成员契约
ensureRequestHeaders()返回已有头,或创建并返回 {}
ensureRequestUrlParams()确保 .path.query 记录存在,返回 Required<UrlParams>
hasError()hasResponse()按真值判断。
requiredResponse返回响应,缺失时抛 ExchangeError
extractResult<R>(): Promise<R>计算一次并缓存值或 Promise,并发调用复用。
response = value替换响应并清空结果缓存。

异步提取被拒绝时保留被拒绝的 Promise 缓存;若提取器尚未返回值/Promise 就同步抛错,则不填充缓存,下次调用可以重试。只修改 resultExtractor 不清除已有缓存。正文只能读取一次;缓存仅避免经 extractResult 重复解析,无法保护直接重复调用 response.json()

提取发生在拦截器管理器结束之后,提取器解析错误不会重新进入错误拦截器。调用者应捕获请求或迭代的拒绝。自定义提取器返回的流由调用者负责读完或取消。

公开辅助类型

PartialBy<T, K> 将指定键变为可选;RequiredBy<T, K> 将指定键变为必填;RemoveReadonlyFields<T> 移除只读键,保留可写键。它们没有运行时行为,也不校验数据。

完整示例

ts
import { Fetcher, FetchExchange, ResultExtractors } from '@ahoo-wang/fetcher';

type User = { id: string; name: string };
const client = new Fetcher();
const exchange = new FetchExchange({
  fetcher: client,
  request: { url: '/users/1' },
  response: Response.json({ id: '1', name: 'Ada' }),
  resultExtractor: ResultExtractors.Json,
});
const first = await exchange.extractResult<User>();
const second = await exchange.extractResult<User>();
console.assert(first === second && first.name === 'Ada');

公开符号与源码

符号实现
AttributesCapablefetchExchange.ts:23
FetchExchangeInitfetchExchange.ts:41
FetchExchangefetchExchange.ts:105
ResultExtractorresultExtractor.ts:23
ResultExtractorCapableresultExtractor.ts:31
ExchangeResultExtractorresultExtractor.ts:42
ResponseResultExtractorresultExtractor.ts:55
JsonResultExtractorresultExtractor.ts:67
TextResultExtractorresultExtractor.ts:79
BlobResultExtractorresultExtractor.ts:92
ArrayBufferResultExtractorresultExtractor.ts:106
BytesResultExtractorresultExtractor.ts:120
ResultExtractorsresultExtractor.ts:131
PartialBytypes.ts:33
RequiredBytypes.ts:52
RemoveReadonlyFieldstypes.ts:85

包索引

基于 Apache License 2.0 发布。