Scala 如何创建一个调用另一个服务并返回未来的方法?

Scala 如何创建一个调用另一个服务并返回未来的方法?,scala,future,Scala,Future,我想定义一个方法,它将返回一个Future。在这个方法中,它将调用另一个服务,该服务还返回一个Future 我们定义了一个BusinessResult来表示Success和Fail: object validation { trait BusinessResult[+V] { def flatMap[T](f: V => BusinessResult[T]):BusinessResult[T] def map[T](f: V => T): BusinessResu

我想定义一个方法,它将返回一个
Future
。在这个方法中,它将调用另一个服务,该服务还返回一个
Future

我们定义了一个
BusinessResult
来表示
Success
Fail

object validation {
  trait BusinessResult[+V] {
    def flatMap[T](f: V => BusinessResult[T]):BusinessResult[T]
    def map[T](f: V => T): BusinessResult[T]
  }

  sealed case class Success[V](t:V) extends BusinessResult[V] {
    def flatMap[T](f: V => BusinessResult[T]):BusinessResult[T] = {
      f(t)
    }
    def map[T](f: V => T): BusinessResult[T] = {
      Success(f(t))
    }
  }

  sealed case class Fail(e:String) extends BusinessResult[Nothing] {
    def flatMap[T](f: Nothing => BusinessResult[T]):BusinessResult[T] = this
    def map[T](f: Nothing => T): BusinessResult[T] = this
  }

}
并定义方法:

import scala.concurrent._
import scala.concurrent.ExecutionContext.Implicits.global
import validation._

def name: BusinessResult[String] = Success("my name")

def externalService(name:String):Future[String] = future(name)

def myservice:Future[Int] = {
  for {
    n <- name
    res <- externalService(n)
  } yield res match {
    case "ok" => 1
    case _ => 0
  }
}
这也是不可编译的


我知道这段代码中肯定有很多问题。如何调整它们以使其可编译?

如果您使用一些硬编码字符串更改
n
,问题在于,在理解变量
n
中有类型
BusinessResult[string]
,您可能已经知道,为了理解,将其分解为
map
flatMap
filter
因此第一部分
n如果
name
是一个
Fail
val value=name.getVal
将抛出异常,这不是预期的。我刚刚添加了一个示例实现,如果它是
Fail
,您会期望什么?您可能知道
选项
getOrElse
方法,您也可以使用类似的方法。这里的问题是如何展开您拥有的自定义类型,这意味着还必须处理可能的异常,我刚才提到了选项,因为它们有很好的方法来展开它们所持有的值。
def myservice:Future[Int] = {
  for {
    nn <- Future.successful(name)
    n <- nn
    res <- externalService(n)
  } yield res match {
    case "ok" => 1
    case _ => 0
  }
}
val test: BusinessResult[String] = name.map(x => x)
type mismatch;
[error]  found   : validation.BusinessResult[Nothing]
[error]  required: scala.concurrent.Future[Int]
[error]       n <- name
[error]         ^
object validation {
  trait BusinessResult[+V] {
    def flatMap[T](f: V => BusinessResult[T]):BusinessResult[T]
    def map[T](f: V => T): BusinessResult[T]
    def getVal: V
  }

  sealed case class Success[V](t:V) extends BusinessResult[V] {
    def flatMap[T](f: V => BusinessResult[T]):BusinessResult[T] = {
      f(t)
    }
    def map[T](f: V => T): BusinessResult[T] = {
      Success(f(t))
    }
    def getVal: V = t
  }

  sealed case class Fail(e:String) extends BusinessResult[Nothing] {
    def flatMap[T](f: Nothing => BusinessResult[T]):BusinessResult[T] = this
    def map[T](f: Nothing => T): BusinessResult[T] = this
    def getVal = throw new Exception("some message")
  }
}

def myservice: Future[Int] = {
  val value = name.getVal
  for {
    res <- externalService(value)
  } yield res match {
    case "ok" => 1
    case _ => 0
  }
}