Try Future sequence
这两天重新看了点儿Erik Meijer讲Try和Future,自己对他所讲内容没有什么违和感了,蛮开心的。
1)关于Option[T], Either[E, R] 和 Try[T]的使用场景。
这三种type很容易让人想到处理Exception的场景。这些types如果只是针对Exception就略显狭隘了。现在我的感觉是:
1)Option适于处理业务逻辑上需要空值的地方,这里不一定是因为Exception导致。往往是业务上需要表达这种“空”/“没值”。
2)Either的左值不一定是Exception,表示一个计算可能有两种结果比较好,右值按照惯例表示正确/正常路径下的结果。左值是另个分支的结果。当然,也可以放Exception,Error什么的。STTP的Response body部分就是一个Either[Error, T]。
3)Try,其实才是最适合表示一个计算可能出现Exception的type。Try的apply()接受的就是一个代码块并运行,对异常封装到子类Failure。
最后的感觉是Option,Either更像标量,是结果的一个静态表示。而Try是动态的,包含了代码的执行及对结果的封装。看Try的定义体会下:
1 | object Try { |
2)Future’s sequence()的实现。
1)这是Erik喜欢的递归方式的实现。
其中两个flatMap都是Future上的flatMap。
1 | def sequence[T](fts: List[Future[T]]): Future[List[T]] = { |
2)通过类型推导,我发现把flatMap()换成了map()也符合类型检查,似乎也也没有大的问题。
1 | def sequence[T](fts: List[Future[T]]): Future[List[T]] = { |
3)Erik通过async,await实现的sequence。
这种方式似乎更容易理解,但风格太不FP了。Erik警告说,如果是基于Future编程,那么不要wait。但是在async块里除外,因为async本身是异步的所以不会阻塞。另外,async/await在模块scala-async里,需要加到sbt的依赖里。
1 | import scala.async.Async.{async, await} |
4)还可以通过Promise来实现。
等磕完promise再说吧。。。