从flatMap和未来到未来的理解

时间:2014-08-20 19:19:39

标签: scala scala-2.9

我想要像runProgram2这样的东西,但目前该部分不能编译。有没有办法像runProgram2那样写它,但它编译..

package transformer

import scala.concurrent.{ExecutionContext, Promise, Future}
import ExecutionContext.Implicits.global
import java.util.concurrent.TimeUnit
import scala.concurrent.duration.Duration

object TestingForComprehensions2 {

    def main(args: Array[String]) = {
      val future1: Future[String] = runMyProgram()
      future1.onSuccess {
        case r:String =>       System.out.println("result="+r)
      }


      val future2: Future[String] = runMyProgram2()
      future2.onSuccess {
        case r:String =>       System.out.println("result="+r)
      }

      System.out.println("waiting")
      Thread.sleep(600000)
    }

    def runMyProgram() : Future[String] = {
      val future = serviceCall()
      val middle = serviceCallWrap(future)
      val future2 = middle.flatMap(serviceCall2)
      val future3 = future2.map(processAllReturnCodes)
      future3
    }

    def runMyProgram2() : Future[String] = {
      for {
        result1 <- serviceCall()
        middle = serviceCallWrap(result1)
        result2 <-  serviceCall2(middle)
      } yield processAllReturnCodes(result2)
    }

    def processAllReturnCodes(theMsg: String) : String = {
      "dean"+theMsg
    }

    def serviceCall() : Future[Int] = {
      val promise = Promise.successful(5)
      promise.future
    }

    def serviceCallWrap(f:Future[Int]) : Future[Int] = {
      f
    }

    def serviceCall2(count:Int) : Future[String] = {
      val promise = Promise.successful("hithere"+count)
      promise.future
    }

}

2 个答案:

答案 0 :(得分:1)

serviceCallWrap期待未来,但您传递Int,第一步是删除result1 <- serviceCall()部分并直接致电middle = serviceCallWrap(serviceCall())

现在middle是未来,但serviceCall2需要Int,在这种情况下,您可以使用middle <- serviceCallWrap(serviceCall())从以后提取未来的值:

def runMyProgram2() : Future[String] = {
  for {
    middle <- serviceCallWrap(serviceCall())
    result2 <-  serviceCall2(middle)
  } yield processAllReturnCodes(result2)
}

如果你想保持理解结构:

def runMyProgram2() : Future[String] = {
  for {
    result1 <- serviceCall()
    middle <- serviceCallWrap(Future(result1))
    result2 <-  serviceCall2(middle)
  } yield processAllReturnCodes(result2)
}

您唯一可以保留(AFAIK)的是middle的分配表达式,如果您想保留需要更改serviceCall2签名的话。虽然这种方法与第一种方法具有完全相同的结果,但它只是更加冗长。

答案 1 :(得分:0)

我想我现在已经弄明白了。或至少这个编译,所以我可以在不同的线上做..... .....

def runMyProgram2() : Future[String] = {
  for {
    result1 <- serviceCall()
    middle <- serviceCallWrap(Promise.successful(result1).future)
    result2 <-  serviceCall2(middle)
  } yield processAllReturnCodes(result2)
}