You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Dartz调用多个Future时如何避免嵌套fold写法

优化方案

dartz的Either本身是右偏向Monad,支持通过链式调用扁平化嵌套逻辑,避免多层fold嵌套,有两种常用实现方式:


方案1:直接使用bind拼接异步结果

适合不想引入额外类型的场景,利用Future的then结合Either的bind方法拼接逻辑,全程仅需1次fold:

final Either<Failure, Unit> result = await deleteA()
    .then((resA) => resA.bind((_) async => await deleteB()));

result.fold(
  (failure) => handleFailure(),
  (success) => handleSuccess(),
);

逻辑说明:

  • 如果deleteA返回Left,bind会直接跳过后续逻辑保留Left值,不会调用deleteB
  • 只有deleteA返回Right时才会执行deleteB,deleteB返回的Left/Right会直接作为最终结果
  • 最终结果的fold分支和你原有嵌套写法的逻辑完全等价

方案2:使用TaskEither封装异步操作(更推荐)

TaskEither是dartz专门为异步Either操作设计的类型,链式调用更顺滑,后续新增步骤也不需要改动结构:

// 把原有异步方法封装为TaskEither
final deleteATask = TaskEither(deleteA);
final deleteBTask = TaskEither(deleteB);

// 链式拼接操作,任意一步失败都会直接短路
final Either<Failure, Unit> result = await deleteATask
    .flatMap((_) => deleteBTask)
    .run();

result.fold(
  (failure) => handleFailure(),
  (success) => handleSuccess(),
);

如果后续需要新增更多串行、前序成功才执行的步骤,直接在链上追加flatMap即可,无任何嵌套:

final result = await deleteATask
    .flatMap((_) => deleteBTask)
    .flatMap((_) => deleteCTask) // 新增第三步,无需嵌套
    .flatMap((_) => deleteDTask) // 新增第四步
    .run();

核心原理

dartz的Either和TaskEither都是右偏向结构,所有转换操作仅作用于成功的Right值,任意一步出现Left(失败)都会直接跳过后续所有操作,保留第一个出现的错误值,完全符合你“前序成功才执行后续”的需求。

内容的提问来源于stack exchange,提问作者Manu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 18:03:03