期货让我们在主线程之外运行值并处理背景,或者尚未由mappin运行值...
期货允许我们在主线程之外运行值,并通过与回调映射它们来处理在后台运行或尚未执行的值。
如果您来自Java背景,您可能会知道java.util.concurrent.Future。使用此方法存在几个挑战:
- 检索值时始终会阻塞线程。
- 计算完成的等待时间。
- 该
GET方法是检索值的唯一方法。
这 是编写并发代码的一种疲惫和敌对的方式。
我们在Scala拥有更好的Future Scala.concurrent.Future。使用Scala Futures,我们可以实现:
- 实时无阻塞计算。
onComplete(成功/失败)的回调,即Future中的值是Try子句的实例。- 多个期货的映射。
期货本质上是不可变的,并在内部进行缓存。一旦指定了值或例外,就无法修改/覆盖期货(很难实现参照透明性)。
简单的例子:
执行上下文
可以将其ExecutionContext视为分配新线程或使用池/当前线程(不推荐)执行Future及其功能的管理员。不导入ExecutionContext范围,我们就无法执行未来。
ExecutionContext在许多情况下,使用Global可以避免创建自定义项的需要ExecutionContext。默认全局变量ExecutionContext将并行度级别设置为可用处理器的数量(可以增加)。
回呼
期货最终返回需要由回调处理的值。 未处理的值/异常将丢失。
期货有您可以使用的方法。常见的回调方法有:
onCompleteFuture中的回调值是该Try子句的实例:
onSuccess并onFailure已弃用。您可以使用filter,foreach,map,还有更多-了解这里。
等待
此方法仅在需要阻塞线程的系统中使用。通常不建议这样做,因为它会影响性能。
Await.result 将阻塞主线程,并等待结果指定的持续时间。
上面的代码将仅显示:

这需要持续时间导入几秒钟。为了处理并发应用程序中的时间,Scala具有:
这种支持不同的时间单位:
toNanos,toMicros,toMillis,toSeconds,toMinutes,toHours,toDays,和toUnit(unit: TimeUnit)。
对于庞大的代码,回调并不总是最好的方法。Scala期货可以与一起使用for (enumerators) yield e,其中enumerators指的是用分号分隔的列表。枚举器可以是引入新变量的生成器,也可以是过滤器。
很高兴知道
例外情况
当异步计算引发未处理的异常时,与这些计算关联的Future将失败。失败的期货存储实例Throwable而不是结果值。Future提供了failed投影方法,该方法可以Throwable将视为另一个的成功值Future。
投影
为了让我们理解作为例外返回的结果,期货也有预测。如果原始的Future失败,则failed投影将返回包含type值的Future Throwable。如果原始的Future成功,则failed投影将失败,并带有NoSuchElementException。
完整的代码
输出量
在使主线程等待两秒钟之后,我们可以看到来自Future线程的输出,如下所示:

结论
期货是一种以高效且无阻塞的方式运行并行程序的好方法。我们可以使用外部库(scalaz,cat等)以更实用的方式实现此目的。
Akka是基于Scala构建的参与者模型库,并提供了一种实现长时间运行的并行流程(克服Scala Futures的局限性)的方法。期货在使用Scala构建的其他框架中使用,例如Play框架,lagom,Apache Spark等。
请查看我们的页面YolkOrbit, 以获取有关Scala和Akka的更多信息。
感谢您的阅读和支持。
主题:
scala, 函数式编程, 分布式计算, 并发, 并行编程, java