Scala未来的理解失败 [英] failure in Scala future's for comprehension

查看:80
本文介绍了Scala未来的理解失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有三个连续的期货,并用于这样的理解中

I have three sequential Futures and use in the for comprehension like this

val comF = for {
  f1 <- future1
  f2 <- future2
  f3 <- future3
} yield {
  // something
}

comF onSuccess { }
comF onFailure { 
  // ----------------      Here is the problem  --------------------------------
  //
  // How do I know which future failed(throw exception), when the callback comes here ?
  // Thanks for the help! Different futures using different exceptions can solve it.
}

现在我有了一个像List [Future [T]]之类的未来列表,首先我使用此方法将其传输到Future [List [T]](

Now I have a future list like List[Future[T]], and first I transfer it to Future[List[T]] using this method (Why does this list-of-futures to future-of-list transformation compile and work?). then I get the future

val fList: Future[List[T]]
fList on Failure {
  // 
  // How do I know which is Fail now >??
}

推荐答案

考虑代码:

def func = {
  try {
    val x = maybeThrows
    val y = maybeThrowsToo
    val z = maybeThrowsAsWell
    result(x, y, x)
  } catch (RuntimeException e) {
    // How do I know which maybeThrows failed?
  }
}

Future情况的工作原理基本上相同.

The Future case works essentially in the same way.

即使List中的分组计算也无济于事:

Even grouping computations in List doesn't help:

def func = {
  try {
    val x = maybeThrows
    val y = maybeThrowsToo
    val z = maybeThrowsAsWell
    val list = List(x, y, z)
    result(list)
  } catch (RuntimeException e) {
    // How do I know which maybeThrows failed?
  }
}


扰流器:您必须跟踪显式的运算失败.如果使用try/catch完成,将导致一些样板.但幸运的是,使用Future(和Try)样板并不坏:


Spoiler: you have to track explicityl which computation failed. It would result in some boilerplate if done with try/catch. But luckily with Future (and Try) the boilerplate isn't that bad:

class TaggedException(val idx, exc: Exception)

def tagFailedWithIndex[T](idx: Int, f: Future[T]): Future[T] = 
  future recoverWith { case exc => Future.failed(new TaggedException(idx, exc)) }

val comF = for {
  f1 <- tagFailedWithIndex(0, future1)
  f2 <- tagFailedWithIndex(1, future2)
  f3 <- tagFailedWithIndex(2, future3)
} yield something(f1, f2, f3)

comF onFailure { 
  case exc: TaggedException => "%d computation failed".format(exc.idx)
}

Spoiler ,您必须明确跟踪哪些计算失败.如果使用try/catch完成,将会导致很多样板.但幸运的是,其中有Try,而Future的表现甚至相同:

Spoiler you have to track which computation failed explicitly. It would result in a lot of boilerplate if done with try/catch. But luckily there is Try, and Future behaves even more the same:

class TaggedException(val idx, exc: Exception)

def tagFailedWithIndex[T](idx: Int, f: Future[T]): Future[T] = 
  future recoverWith { case exc => Future.failed(new TaggedException(idx, exc)) }

val comF = for {
  f1 <- tagFailedWithIndex(0, future1)
  f2 <- tagFailedWithIndex(1, future2)
  f3 <- tagFailedWithIndex(2, future3)
} yield something(f1, f2, f3)

comF onFailure { 
  case exc: TaggedException => "%d computation failed".format(exc.idx)
}

这篇关于Scala未来的理解失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆