我想做的是使用 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
来查看两个变量。
为什么当我只打印时可以按照我的预期执行该程序?
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)))