thenWith<R, E> method

Future<ChainResult<M, R>> thenWith<R, E>(
  1. Future<Response<R>> nextRequest(
    1. M extracted
    ), {
  2. E? extractor(
    1. Response<R> response
    )?,
  3. M updater(
    1. M extracted,
    2. E? extractedValue
    )?,
})

链式调用:传递提取后的对象给下一个请求 返回 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,
  );
}