thenWith<R, E> method
链式调用:传递提取后的对象给下一个请求 返回 ChainResult,对象在链路中传递
参数说明:
nextRequest: 下一个请求(必需),接收提取的对象作为参数extractor: 从响应中提取数据(可选),如果提供,会提取数据用于更新对象updater: 更新对象(可选),如果提供,会用提取的数据更新对象
示例1:中间步骤,不更新对象
final result = await http.isLoading
.send(...)
.extractModel<FileUploadResult>(FileUploadResult.fromConfigJson)
.thenWith((uploadResult) => http.send(
method: hm.post,
path: '/get-url',
data: {'key': uploadResult.imageKey},
));
示例2:中间步骤,更新对象并继续链式调用
final result = await http.isLoading
.send(...)
.extractModel<FileUploadResult>(FileUploadResult.fromConfigJson)
.thenWith(
(uploadResult) => http.send(
method: hm.post,
path: '/get-image-url',
data: {'image_key': uploadResult.imageKey},
),
extractor: (response) => response.extractField<String>('image_url'),
updater: (uploadResult, imageUrl) => uploadResult.copyWith(imageUrl: imageUrl),
)
.thenWith((updatedUploadResult, prevResponse) => http.send(...)); // 可以继续链式调用
Implementation
Future<ChainResult<M, R>> thenWith<R, E>(
Future<Response<R>> Function(M extracted) nextRequest, {
E? Function(Response<R> response)? extractor,
M Function(M extracted, E? extractedValue)? updater,
}) async {
// 关键修复:在 await this 之前检查 hasChainLoading,避免 finally 块中的 Future.microtask 清空 _chainLoadingId
// 这样即使 finally 块执行,也不会影响已保存的状态
final hasChainLoading = HttpUtilSafeCall.hasChainLoading();
final extracted = await this;
if (extracted == null) {
// 注意:这里无法创建 ChainResult,因为 extracted 为 null
// 检查是否有链式调用的加载提示,如果有则关闭
if (hasChainLoading) {
HttpUtilSafeCall.closeChainLoading();
}
throw StateError('提取的对象为 null,无法继续链式调用');
}
final response = await nextRequest(extracted);
// 如果提供了 extractor 和 updater,提取数据并更新对象
M finalExtracted = extracted;
if (extractor != null && updater != null) {
final extractedValue = extractor(response);
finalExtracted = updater(extracted, extractedValue);
}
return ChainResult<M, R>(
extracted: finalExtracted,
response: response,
hasChainLoading: hasChainLoading,
);
}