温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Future的sequence怎么实现

发布时间:2021-12-27 15:51:28 来源:亿速云 阅读:144 作者:iii 栏目:互联网科技

这篇文章主要讲解了“Future的sequence怎么实现”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Future的sequence怎么实现”吧!

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的定义体会下:

object Try {  def apply[T](r: => T): Try[T] =    try Success(r) catch {      case NonFatal(e) => Failure(e)    }}

2)Future's sequence()的实现。

1)这是Erik喜欢的递归方式的实现。

其中两个flatMap都是Future上的flatMap。

def sequence[T](fts: List[Future[T]]): Future[List[T]] = {  fts match {    case Nil => Future(Nil)    case ft::fts => ft.flatMap( t => sequence(fts).flatMap(ts => Future(t::ts)))  }}

2)通过类型推导,我发现把flatMap()换成了map()也符合类型检查,似乎也也没有大的问题。但在逻辑上,这个实现就是要要等着所有的future依次从尾部开始都complete了才能执行。而上面的实现整个过程都是异步的,更符合Future的原意。

def sequence[T](fts: List[Future[T]]): Future[List[T]] = {  fts match {    case Nil => Future(Nil)    case ft::fts => ft.flatMap( t => sequence(fts).map(ts => t::ts))  }}

3)Erik通过async,await实现的sequence。

这种方式似乎更容易理解,但风格太不FP了。Erik警告说,如果是基于Future编程,那么不要wait。但是在async块里除外,因为async本身是异步的所以不会阻塞。另外,async/await在模块scala-async里,需要加到sbt的依赖里。

import scala.async.Async.{async, await}def sequence[T](fs: List[Future[T]]): Future[List[T]] = async {  var _fs = fs  val result = ListBuffer[T]()  while (_fs != Nil) {    result += await { _fs.head }    _fs = _fs.tail  }  result.toList}

感谢各位的阅读,以上就是“Future的sequence怎么实现”的内容了,经过本文的学习后,相信大家对Future的sequence怎么实现这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI