使用 DartZ 调用多个 Future 时如何避免嵌套折叠?

问题描述 投票:0回答:1

我有一段代码,如下所示:

final Either<Failure, Unit> resA = await deleteA();

resA.fold(
  (failure) => handleFailure(),
  (success) async {
    final Either<Failure, Unit> resB = await deleteB();
    resB.fold(
      (failure) => handleFailure(),
      (success) => handleSuccess(),
    );
  },
);

基本上,我想调用第一个函数,它返回失败或单位(成功值并不重要)。

然后,如果第一个函数成功,我想调用另一个函数,它也返回 Future 或 Unit。

我该如何避免在另一个

fold
中进行
fold
的丑陋嵌套调用?

我正在使用包 dartz,这真的很酷,但缺乏文档。

flutter dart asynchronous future dartz
1个回答
0
投票

这个问题好像已经两年没有答案了,最近我对Dart中的函数式编程产生了兴趣,在这里我尝试回答一下。

您可以使用

traverseFuture
继续下一个异步过程,使用
then
链接未来,并使用
bind
绑定结果。最后,折叠结果。这是代码:

final Either<Failure, Unit> resA = await deleteA();
resA
  .traverseFuture((w) => deleteB())
  .then((x) => x.bind((y) => y))
  .then((z) => z.fold(
        (l) => handleFailure(l.msg),
        (r) => handleSuccess(),
      ));

上面的代码还可以再简化一下。您可以直接调用并链接

deleteA()
,而不将其存储到变量中,将
bind
fold
链接在一行中,并将
bind((y) => y)
更改为
bind(id)
id
表示来自 dartz 包
f(x) = x 的身份) 
)。

这是简化的代码:

deleteA()
  .then((resA) => resA.traverseFuture((w) => deleteB()))
  .then((x) => x.bind(id).fold(
        (l) => handleFailure(l.msg),
        (r) => handleSuccess(),
      ));

没有 ifs 语句,没有嵌套折叠,只有一个链接函数语句 ✨

结果呢?错误处理怎么样?结果与之前对双折所做的结果保持不变,上面的代码(单折)使用了面向铁路的编程原理(ROP),如下所示

ROP

所以如果

deleteA
失败,
deleteB
将不会被执行。

这是错误处理演示和结果输出:

demo

希望能解决您的问题,谢谢😉

© www.soinside.com 2019 - 2024. All rights reserved.