为什么已完成的Scala Future用于for推导后返回未完成状态
问题原因解析
核心问题本质
你到Step1的判断是完全正确的,此时twenty确实已经处于Success(20)的完成状态,问题出在Future转换操作的调度逻辑上。
Scala中所有基于Future的转换操作(包括for推导对应的map/flatMap),哪怕依赖的上游Future已经完成,转换逻辑也不会在当前线程同步执行,而是会被提交到你导入的ExecutionContext.Implicits.global线程池的任务队列中,等待异步调度执行。
你在定义完myresult之后立刻打印它,此时线程池还没来得及调度执行bb * 2的转换逻辑,所以myresult还处于未完成状态,就输出了Future(<not completed>)。
你存在的理解误区
- 误区1:误以为上游Future完成后,基于它的转换操作会立刻同步执行完成。实际上所有Future的转换逻辑都是异步调度的,不会占用当前主线程的执行时序。
- 误区2:直接打印Future对象只会输出它的瞬时状态,不会主动等待Future完成。如果需要获取转换后的结果,需要显式等待
myresult完成。
验证方法
你可以在打印Step2之前,添加等待myresult完成的逻辑,就能拿到预期的40:
// 原有代码不变 val myresult = for { bb: Int <- twenty } yield { bb * 2 } // 新增等待myresult完成的逻辑 while (!myresult.isCompleted ) { Thread.sleep(100) } println("Step 2: " + myresult)
修改后输出会变为:
twenty onComplete: 20 Step 1: Future(Success(20)) Step 2: Future(Success(40))
如果需要直接拿结果值,也可以用Await.result:
import scala.concurrent.duration._ val res = Await.result(myresult, 1.second) println("Step 2 结果值:" + res) // 输出40
内容的提问来源于stack exchange,提问作者mbsf
相关产品推荐
相关产品推荐

