结合期货(Twitter)和Scala中的任何一种
发布时间:2020-12-16 18:12:19 所属栏目:安全 来源:网络整理
导读:我们使用Twitter期货(作为Finagle堆栈的一部分),我不喜欢使用(业务)异常来控制应用程序流的概念,因为异常不会出现在方法签名中. 所以我有了使用Future [Aither [A,B]]作为替代品的想法. 但是我使用这个概念来使用对期货的理解存在一些问题: 例如.我们有一个
我们使用Twitter期货(作为Finagle堆栈的一部分),我不喜欢使用(业务)异常来控制应用程序流的概念,因为异常不会出现在方法签名中.
所以我有了使用Future [Aither [A,B]]作为替代品的想法. 但是我使用这个概念来使用对期货的理解存在一些问题: 例如.我们有一个存储库方法: def getUserCredentialsByNickname(nickname: String): Future[Either[EntityNotFound,UserCredentials]] 和一个处理程序方法,它使用这个repo并做一些其他检查,并创建一个令牌 def process(request: LoginRequest): Future[Either[Failure,Login]] = { for { credentialsEither <- userRepository.getUserCredentialsByNickname(request.username) ...several other calls/checks which should 'interrupt' this for comprehension token <- determineToken(credentials) } yield token getUserCredentialsByNickname(..)之后的for comprehension中的调用只应在此调用返回Right [UserCredentials]时执行,而且应从处理程序返回每个返回的Either的详细错误信息. 解决方法
所以现在我已经尝试使用Scalaz Either(这是一个正确的偏向Either与中性scala Either相比)和Monad Transformer EitherT,它似乎完全符合我的要求.感谢Huw,特别是Lars Hupel暗示我正确的方向.
这里有一个Twitter期货和Scalaz Either和EitherT的样本: import com.twitter.util.{Await,Future} import scalaz.{Monad,Functor,EitherT,/} import scalaz.syntax.ToIdOps object EitherTest extends App with ToIdOps{ // make Twitter futures work with EitherT implicit val FutureFunctor = new Functor[Future] { def map[A,B](a: Future[A])(f: A => B): Future[B] = a map f } implicit val FutureMonad = new Monad[Future] { def point[A](a: => A): Future[A] = Future(a) def bind[A,B](fa: Future[A])(f: (A) => Future[B]): Future[B] = fa flatMap f } // The example begins here: case class InvalidInfo(error: String) case class Response(msg: String) class ComponentA { def foo(fail: Boolean): Future[/[InvalidInfo,Response]] = { if(fail) Future(InvalidInfo("Error A").left) else Future(Response("ComponentA Success").right) } } class ComponentB { def bar(fail: Boolean): Future[/[InvalidInfo,Response]] = { if(fail) Future(InvalidInfo("Error B").left) else Future(Response("ComponentB Success").right) } } val a = new ComponentA val b = new ComponentB val result = for { resultA <- EitherT(a.foo(false)) resultB <- EitherT(b.bar(false)) } yield (resultA,resultB) println(Await.result(result.run)) } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |