Scala Future没有像我预期的那样运行

时间:2016-06-21 16:46:43

标签: scala future

我想要做的是使用Future打开一个线程来处理可以经常调用的异步任务。

但在async task。我还调用了两个Future函数来从不同的数据源获取信息。

我写了一个程序来模拟这种情况。

import scala.concurrent.{ExecutionContext, Future}
import scala.util.{Success, Failure}
import scala.util.control.Breaks
import ExecutionContext.Implicits.global
object AsyncTest {


  def main(args: Array[String]) {
    try {
      println("Run...")
      aSyncTask
    } catch {
      case e => e.printStackTrace()
    }

    Thread.sleep(999999)
  }
  //dataSource1
  def getInfo1 : Future[String]  = Future{
    "A"
  }
  //dataSource2 let it wait 3 seconds...
  def getInfo2 : Future[String]  = Future{
    Thread.sleep(3000)
    "B"
  }

  def aSyncTask = Future{
    getInfo1
    getInfo2

    var result1 : String = null
    var result2 : String = null

    getInfo1.onComplete{
      case Success(value) => result1 = value
      case Failure(t) => println {
        "An error has occured: " + t.getMessage
      }
    }

    getInfo2.onComplete{
      case Success(value) => result2 = value
      case Failure(t) => println {
        "An error has occured: " + t.getMessage
      }
    }
    /*I want to wait both Future function completed then
      I can do some business logic */
    Breaks.breakable{
      while (true) {
        if (result1 != null && result2 != null)
          Breaks.break
      }
    }

    println("----------------------")
    println("result1:"+result1)
    println("result2:"+result2)
    println("----------------------")
  }

}

在我编译并执行了这个程序后,它什么也没输出。只是等待。

Run...

我希望我能看到输出:

Run...
----------------------
result1:A
result2:B
----------------------

所以,我在while循环中添加了一些代码用于调试。

    Breaks.breakable{
      while (true) {
        println(result1)
        println(result2)
        if (result1 != null && result2 != null)
          Breaks.break
      }
    }

然后输出:

Run...
A
null
A
null
A
null
A
null
A
null
(After 3 seconds...)
A
B
----------------------
result1:A
result2:B
----------------------

发生什么事了?我只需添加两个println来查看两个变量。

为什么程序可以像我预期的那样在我打印时执行?

1 个答案:

答案 0 :(得分:0)

Future被创建为可组合的,所以我会冒险并假设你想要这样的东西:

// Important to initialize them outside of for comprehension
val (f1, f2) = (getInfo1, getInfo2)
val ab: Future[(String, String)]  = 
  for {
    r1 <- f1
    r2 <- f2
  } yield (r1, r2) // Do whatever you want to do with r1 and r2

println(Await.result(ab, Duration(10000, MILLISECONDS)))