繁体   English   中英

如何验证Future [List [T]]中的单个元素以返回Future [List [T]]或引发异常

[英]How to validate single element in Future[List[T]] to return Future[List[T]] or throw exception

此处无需注意功能的用途,仅用于演示:

def readAllByPersonOrFail(person: Person, otherPersonId: Long): Future[List[Person]] = {
  val personSiblingsFuture: Future[List[Person]] = personSiblingsDomain.readAllByPersonId(person.id)
  personSiblingsFuture.map { persons =>
    persons.find(_.id == otherPersonId) match {
      case Some(person) =>
        person.isActive match {
          case true => person
          case false => throw new IllegalArgumentException("something inactive")
        }
      case None => throw new IllegalArgumentException("something wrong ehre")
    }
  }
  personSiblingsFuture
}

如果验证,我想返回上面的personSiblingsFuture(确保正确的人在列表中并且处于活动状态),否则抛出异常。 我不认为上面的代码做对了,因为失败后就不存在了。

看一下scala.concurrent.Future.map 这将创建一个新的未来,其价值可以通过将函数应用于该未来的成功结果来解决。

请注意,这里您还将丢弃刚刚使用.map()创建的结果。

尽管您应该更深地质疑Futures中异常的使用,但仍有一些地方可以解决您的问题。 Scala提供了诸如FutureOptionTry类的概念,专门用于避免引发异常并具有更清晰的控制流程。

选项1,返回映射的将来

在您的功能中

def func(...): Future[List[Person]] {
  val personSiblingsFuture = ...;
  personSiblingsFuture.map { persons =>
    ...
  }
}
// note we're not returning personSiblingsFuture,
// but the mapped result

当某人实际上尝试获取未来的价值时,例如通过使用.value ,他们可能会看到一个异常提示:

def main() {
  val future = func(...);  // this is fine
  val my_list = future.value;  // awaits Future, might throw here
}

选项2,实际上等待列表并放入函数

返回一个可能抛出的未来很奇怪,如果您实际上明确地拥有一个可能抛出的函数,则可能会容易一些。

/** jsdoc describing function **/
def funcMightThrow(...): List[Person] {
  val personSiblingsFuture = ...;
  val personSiblings = personSiblingsFuture.value;

  personSiblings.find(_.id == otherPersonId) match {
    case Some(person) =>
      person.isActive match {
        case true => personSiblings
        case false => throw new IllegalArgumentException("something inactive")
      }
    case None => throw new IllegalArgumentException("something wrong ehre")
  }
}

选项3,考虑使返回类型更明确

def func(...): Future[Try[List[Person]]] {
  val personSiblingsFuture = ...;
  personSiblingsFuture.map { persons =>
    ...
    // successful case returns 'persons' (List[Person])
    // fail cases return Failure(...) instead
  }
}  // return the mapped future

您也可以使用.value返回Try[List[Person]]而不是其中的Future[] ,这会使func成为阻塞函数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM