2.6 对比Future

本小节,我们可以通过比较Scala标准库中的ZIO和Future来阐明到目前为止所学的知识。
在本书后面讨论并发性时,我们将讨论ZIO和Future之间的其他差异,但目前要记住三个主要差异。

2.6.1 一个 Future 就是一个正在运行的 effect

与ZIO之类的函数式作用不同,Future是对运行时的作用进行建模。 回到先前的一个示例,请考虑以下代码段:

  import scala.concurrent.Futureimport scala.concurrent.ExecutionContext.Implicits.globalval goShopping: Future[Unit] = Future(println("Going to the grocery store"))

就像我们最初的示例一样,一旦定义goShopping,此效果就会开始执行。 Future不会暂停对其中包装的代码的运行。
由于"做什么"与"怎么做"之间存在纠结,在Future显得并不是那么强大。例如,就像在ZIO上一样,能够在Future上定义一个延迟运算符会很好。但是我们不能这样做,因为一个Future一旦存在,它就已经开始运行,没有机会再延迟计算。
同样,在失败的情况下我们也不能像ZIO那样重试Future,因为Future并不是做某事的蓝计划,而是一种执行性的计算。因此,如果Future失败,则无事可做。我们只能检索失败。
相比之下,由于ZIO effect是并发工作流程的蓝图,因此,如果执行一次该效果但失败了,我们可以随时尝试再次执行它,或者执行任意多次。
这种区别特别明显的一种情况是,每当您在Future上调用方法时,您就必须在范围内具有隐式ExecutionContext。

例如,这是Future#flatMap的签名,与ZIO上的flatMap一样,它使我们可以编写顺序效果:

  import scala.concurrent.ExecutionContexttrait Future[+A] {def flatMap[B](f: A => Future[B])(implicit ec: ExecutionContext): Future[B]}

Future#flatMap需要一个ExecutionContext,因为它表示一个运行中的effect,因此我们需要提供ExecutionContext,随后的代码应在该ExecutionContext上立即运行。
如前所述,这将"要完成的工作"与"如何完成的工作"混为一谈。 相反,我们所见的涉及ZIO的代码都不需要执行程序,因为它只是一个蓝图。
ZIO蓝图可以在我们想要的任何Executor上运行,但是在实际运行效果之前,不必指定它(或者稍后,我们将看到如何 “lock” 效果以在特定 execution context 中运行,那些罕见的情况
您需要对此明确说明)。

2.6.2 Future的错误类型固定为Throwable

Future的错误类型固定为Throwable。 我们可以在Future#onComplete的签名中看到这一点:

  import scala.util.Trytrait Future[+A] {def onComplete[B](f: Try[A] => B): Unit}

Future的结果可以是成功返回一个A,也可以是抛出Throwable的失败。 当使用可能因任何Throwable失败而遗留的旧代码时,这可能很方便,但与多态错误类型相比,它的表达能力要低得多。
首先,通过查看类型签名,我们不知道effect如何失败或甚至是否会失败。 考虑一下我们讨论用Future实现的ZIO错误类型时所看的乘法示例:

def parseInt: Future[Int] = ???

注意,由于Future是运行时的effect,因此我们必须将其定义为def而不是val。因此,如果我们将其定义为val,我们将立即读取并解析用户的输入。然后,当我们使用parseInt时,我们总是会获得相同的值,而不是提示用户输入新值并进行解析。
抛开这一点,我们不知道通过查看类型签名,未来会如何失败。它可以从解析中返回NumberFormatException吗?它可以返回IOException吗?它会因为自己处理错误而完全失败,也许是通过重试直到用户输入有效的整数为止?我们只是不知道,除非我们深入研究代码并进行深入研究。
这对于调用此方法的开发人员来说更加困难,因为他们不知道会发生哪种类型的错误,因此为了安全起见,他们需要进行“防御性编程”并处理所有可能的Throwable。
当我们处理Future的所有可能的失败方案时,此问题尤其令人讨厌。
例如,我们可以使用Future方法fallbackTo处理parseInt错误:

  import scala.concurrent.Futuredef parseIntOrZero: Future[Int] = parseInt.fallBackTo(Future.successful(0))

这里parseIntOrZero不会失败,因为如果parseInt失败,我们将其替换为成功结果0。但是类型签名并没有告诉我们。 就类型签名而言,此方法可能会无限多种方式失败,就像parseInt!一样!
从编译器的角度来看,fallBackTo并没有改变Future的易错性。 相反,在ZIO中,parseInt将具有IO [NumberFormatException,Int]类型,而parseIntOrZero将具有UIO [Int]类型,从而精确地指示parseInt如何失败以及parseIntOrZero无法失败。

2.6.3 Future 没有办法来对 effect 的依赖关系来建模

到目前为止,我们看到的ZIO和Future之间的最终区别是Future没有任何方法可以对effect的依赖性进行建模。 这需要其他解决方案来进行依赖注入,这些解决方案通常是手动的(无法推断),或者依赖于第三方库。
在本书的后面,我们将花更多的时间在此上,但是现在仅需注意ZIO直接支持依赖项注入,而Future没有。 这意味着在实践中,现实世界中的大多数Future代码并不是可测试的,因为它需要太多的管道和样板。

2.6 zio入门——对比Future相关推荐

  1. 2.7 zio入门——更多的Effect构造函数

    2.7 更多的Effect构造函数 在本章的前面,我们了解了如何使用ZIO.effect构造函数将过程代码转换为ZIO效果.ZIO.effect构造函数是一种有用且通用的效果构造函数,但并不适合所有情 ...

  2. 2.5 zio入门——ZIO类型别名

    2.5 ZIO类型别名 ZIO的三个类型参数,功能极为强大.我们可以使用环境类型参数进行参数注入(数据库,连接池,配置等),并且可以使用错误和成功类型参数返回结果. 在最常见的情况下,程序需要向下传播 ...

  3. 第二章 zio 入门

    首先祝贺你开始正式步入研究zio的旅程! ZIO将帮助您构建并发,有弹性,高效且易于理解和测试的现代应用程序. 但是学习ZIO要求以一种全新的角度来思考软件-从函数式编程的角度. 这一章会教会你一些理 ...

  4. 2.8 zio入门——标准ZIO服务

    2.8 标准ZIO服务 在本章的前面,我们讨论了ZIO环境类型,但是我们还没有使用它来编写任何程序. 在本书的后面,我们将深入介绍环境,并说明该环境如何为依赖项注入问题提供全面的解决方案. 现在,我们 ...

  5. 2.1 zio入门——把函数作用作为工作蓝图

    ZIO标准库的核心数据类型是ZIO[R, E, A],这种类型的值被称为函数式作用 函数式作用是并发工作流的一种蓝图,如图1所示.该蓝图本质上是纯描述性的,必须执行才能观察到任何副作用,例如与数据库的 ...

  6. 2.4 zio入门——ZIO类型参数

    2.4 ZIO类型参数 我们之前说过,类型 ZIO [R,E,A]的值是一种 functional effect,需要环境R,并且可能因E失败或成功返回A. 现在,我们也了解了ZIO effect 成 ...

  7. 2.3 zio入门——一些常见的zio操作符

    2.3 其他的一些顺序操作符 按顺序组合是functional effect 最基本的操作,ZIO提供了各种相关的运算符来满足通用需求. zipWith 最基本的是zipWith,它将顺序地合并两个e ...

  8. 2.2 zio入门——按顺序组合ZIO

    2.2 按顺序组合ZIO 正如上小节所述,ZIO效果是描述并发工作流的蓝图,并且我们通过转换和组合更小,更简单的效果来构建更复杂的效果,从而解决业务问题. 我们看到了如何使用 ZIO 的 delay ...

  9. 2.10 zio入门——总结

    2.10 总结 函数式作用是并发工作流的蓝图,不可变的值提供了多种运算符,用于转换和组合effect以解决更复杂的问题. ZIO类型参数使我们可以对需要上下文提供环境才能执行的作用进行建模:它们使我们 ...

最新文章

  1. SAP MM 同一个序列号可以被多次用在交货单发货过账?
  2. udp_socket聊天器demo
  3. 用 JMeter 测量性能--测试您的 DB2 数据库
  4. 固定底部 布局_Google Flutter 布局(四)-Baseline IntrinsicWidth详解
  5. 五、python模块以及包
  6. 利用URL拼接爬取获取有道翻译内容
  7. Linux——k8s命令别名修改
  8. CTF之Web安全训练前篇1
  9. 100 - k8s源码分析-准备工作
  10. 在线网络投票/打分活动实施步骤及疑难问题汇编
  11. Atitit wsdl的原理attilax总结
  12. Model Representation--machine learning
  13. mysql食堂系统E R图_食堂管理系统E-R图.doc
  14. MCSA/MCSE Windows Server 2016认证的学习目录
  15. 手机sim卡插到电脑上网_怎么用手机卡在电脑上上网
  16. 【JZOJ】 【NOIP2014】【模拟试题】保镖排队
  17. python3里复数的算法_Python高级复数算法
  18. IDEA主题配置--- 炫酷的主题字体颜色设置(基于Intellij IDEA 2018)
  19. VMware16虚拟机安装
  20. 数据解读热门美剧 | 《权力的游戏》花式死亡图鉴

热门文章

  1. python操作word详细操作_Python操作Word的入门教程
  2. 单片机霹雳灯双灯c语言,HOLTEK单片机-8LED霹雳灯
  3. UICC 之 USIM 详解全系列——UICC基础知识介绍
  4. Git 安装win7
  5. (前端)html与css,html 6、_a标签
  6. 2021.4.19-2021.4.25周报
  7. 用fiddler+chrome搞定在线学习网站
  8. ACE的CDR中的字节对齐问题
  9. MAtlab wavefront,MATLAB:像Wavefront算法一样制作矩阵
  10. 波前边缘检测 Wavefront Frontier Detector