gpt4 book ai didi

scala - 在 Scala 中结合 Futures (Twitter) 和两者

转载 作者:行者123 更新时间:2023-12-05 00:28:34 26 4
gpt4 key购买 nike

我们使用 Twitter future (作为 Finagle 堆栈的一部分),我不喜欢使用(业务)异常来控制我们的应用程序流程的概念,因为异常不会出现在方法签名中。

所以我有了用 Future[Either[A,B]] 作为替代品的想法。

但是我在使用这个概念来理解 future 时遇到了一些问题:

例如。我们有一个存储库方法:

def getUserCredentialsByNickname(nickname: String): Future[Either[EntityNotFound, UserCredentials]]

以及使用此 repo 并执行一些其他检查并创建 token 的处理程序方法
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] 时才执行,但每个返回的任何详细错误信息都应从处理程序返回。

最佳答案

所以现在我已经尝试使用 Scalaz 或者(与中性的 scala 相比,这是一个正确的偏向或者)和 Monad Transformer EachT,它似乎完全符合我的要求。感谢 Huw,尤其是 Lars Hupel,他向我暗示了正确的方向。

这是 Twitter future 和 Scalaz Each 和 EachT 的示例:

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))
}

关于scala - 在 Scala 中结合 Futures (Twitter) 和两者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18828067/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com