Scala 中的同步和异步客户端代码

Synchronous and Asynchronous client code in Scala

这是我的旧 question 的后续。假设我需要同步和异步调用 REST 服务 both。在同步情况下,我想在调用者线程上执行它而不从池中获取其他线程。

我只想编写我的业务逻辑一次并在这两种情况下重用它。业务逻辑包括构建请求和处理响应。

我也想编写 REST 调用,就像在"invoke service A and then service B and then service C"

中一样

在 Scala 中你会怎么做?

这应该运行在当前线程中...

{
  val currentThreadEx = new AbstractExecutorService {
    override def execute(r: Runnable) { r.run }
    override def shutdownNow(): java.util.List[Runnable] = new java.util.ArrayList[Runnable]()
    override def shutdown() {}
    override def isTerminated = false
    override def isShutdown = false
    override def awaitTermination(timeout: Long, unit: TimeUnit) = false
  }
  implicit val exContext = ExecutionContext.fromExecutor(currentThreadEx)

  val f = Future {
    10 + 1
  } 

  println(Await.result(f, 1 seconds))
}

这将 运行 在默认执行器上...

{
  import ExecutionContext.Implicits.global

  val f = Future {
    10 + 1
  } 

  println(Await.result(f, 1 seconds))
}

如您所见,可以使用ExecutorService作为抽象点。

或者您可以使用根据 Monad 编写的函数,然后您可以将这些操作绑定在一起而无需处理上下文(即 Future)。

  def op1[M[_]: Monad](i: Int)(j: Int): M[Int] = {
    Monad[M].point { i * j }
  }

  println(Monad[Id].point(10) >>= op1[Id](10))
  println((Future { 10 } >>= op1[Future](10)).run)