斯卡拉摆脱了嵌套的未来

时间:2016-04-20 12:43:17

标签: scala nested future

请你帮我写一个更好的方法:

Future {
    Thread sleep 200
    5
} onComplete{
    case Success(e) => Future {
        doSomething(e)
        Thread sleep 200
        6
    } onComplete {
        case Success(e) =>
            Future {
                doSomething(e)
                Thread sleep 200
            } onComplete {
                case Success(_) => println("finished")
                case Failure(e) => e.printStackTrace()
            }
        case Failure(e) => e.printStackTrace()
    }

    case Failure(e) => e.printStackTrace()
}

现在代码看起来很糟糕,如果我以这种方式添加更多的期货,它会变得更糟......这显然是一个展示问题的例子,所以我希望提到更广泛的背景。

@update 如果不够清楚,我会尽力澄清。我有三个期货,并希望执行第一个,当它完成执行第二个,当它完成 - 第三个。第二个未来使用第一个的结果,第三个使用第二个的结果。如果期货之一失败,则打印堆栈跟踪并且调用序列中断。这就是我想在上面的代码中展示的内容,如果可能的话,我希望以更好的,非嵌套的方式实现它。

@update 2 如果我能分别处理每个未来的失败,也会很棒

1 个答案:

答案 0 :(得分:4)

与收藏品非常相似,您可以map()flatMap()期货(scaladoc)将它们组合在一起:

Future {
  Thread sleep 200
  5
}.map { result =>
  doSomething(result)
  Thread sleep 200
  6
}.map { result =>
  doSomething(result)
  Thread sleep 200
}.onComplete {
  case Success(_) => 
    // All steps completed successfully
    println("finished")
  case Failure(e) => 
    // This can be a failure from any of the steps
    e.printStackTrace()
}

map生成结果,而flatMap生成Future实例。

或者你可以使用for-comprehension,这只是(平面)地图调用的语法糖。