scala 我怎样才能扁平化这个 Future[T] 结构?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15835222/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 05:09:04  来源:igfitidea点击:

How can I flatten this Future[T] structure?

scalaasynchronousfuture

提问by Maurício Linhares

Given the following example:

给出以下示例:

  val handler : Connection = new DatabaseConnectionHandler()
  val result : Future[Future[Future[Option[ResultSet]]]] = handler.connect
    .map( (parameters) => handler )
    .map( connection => connection.sendQuery("BEGIN TRANSACTION SERIALIZABLE") )
    .map( future => future.map( query => query.rows ) )
    .map( future => handler.sendQuery("COMMIT").map( query => future ) )

Is it possible to flatten it to receive a Future[Option[ResultSet]]at the end instead of this future inside a future inside a future structure in Scala?

是否有可能将其展平以Future[Option[ResultSet]]在 Scala 的未来结构中的未来内部接收一个,而不是这个未来?

I am currently using Scala's 2.10 Future's and Promise's, but I can't find a way to to this. I know I can use nested callbacks but I would rather avoid that since the code is going to look horrible.

我目前正在使用 Scala 的 2.10 Future 和 Promise,但我找不到解决这个问题的方法。我知道我可以使用嵌套回调,但我宁愿避免这样做,因为代码看起来很糟糕。

The Connectiontrait is defined here.

Connection特性被定义在这里

回答by Debilski

Whenever you mapwith an argument of type A => Future[B]you should really be using flatMap.

每当您map使用类型参数时,A => Future[B]您都应该真正使用flatMap.

The code would then be like this:

代码将是这样的:

  val connection : Connection = new DatabaseConnectionHandler( DefaultConfiguration )
  val result: Future[QueryResult] = connection.connect
    .flatMap( _ => connection.sendQuery("BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ") )
    .flatMap( _ => connection.sendQuery("SELECT 0") )
    .flatMap( _ => connection.sendQuery("COMMIT").map( value => query ) )

Alternatively, you could use for-comprehension. It uses flatMapfor you.

或者,您可以使用 for-comprehension。flatMap为你使用

val connection : Connection = new DatabaseConnectionHandler( DefaultConfiguration )
val result: Future[QueryResult] = for {
  _ <- connection.connect
  _ <- connection.sendQuery("BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ")
  _ <- connection.sendQuery("SELECT 0")
  queryResult <- connection.sendQuery("COMMIT").map( value => query )
} yield { queryResult }

回答by axel22

You should use a flatMapinstead of a maphere.

您应该flatMapmap这里使用 a而不是 a 。

The flatMapexpects a function funreturning a future gand returns the future hholding the value from the future gthat funreturned.

flatMap预期函数fun返回一个未来g,并返回将来h拿着从未来的价值gfun返回。

Also, consider writing this within a for-comprehension, see how here.

另外,请考虑在for-comprehension 中编写此内容,请参阅此处