【问题标题】:Scala getting rid of nested futuresScala 摆脱嵌套的期货
【发布时间】:2016-04-20 21:36:39
【问题描述】:

你能帮我写一个更好的方式吗:

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 如果我能分别处理每个未来的失败,那也很棒

【问题讨论】:

  • 不清楚你想要达到什么目的
  • 好的,我更新了问题

标签: scala nested future


【解决方案1】:

就像集合一样,您可以通过 map()flatMap() Futures (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-comprehensions,它只是(平面)map 调用的语法糖。

【讨论】:

  • 谢谢,但是我可以用这种方法分别处理每个 Future 的失败吗?
  • 你可以检查/匹配你在失败中得到了什么样的 throwable,但不能说到底是哪一步导致了它(当然,除非每个步骤都抛出一个独特的 throwable 类型)。 The accepted answer in this thread explains it well.
猜你喜欢
  • 2013-12-15
  • 2021-03-17
  • 1970-01-01
  • 2020-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-12
  • 2019-08-28
相关资源
最近更新 更多