简体   繁体   English

反向Future.sequence

[英]Reverse of Future.sequence

I know that a Future.sequence call can convert a List[Future[T]] to a Future[List[T]] , but what if I want to go the other way around? 我知道Future.sequence调用可以将List[Future[T]]转换为Future[List[T]] ,但如果我想Future.sequence呢?

I want to convert a Future[List[T]] into a List[Future[T]] . 我想将Future[List[T]]转换为List[Future[T]]

The reason why I want to do this is as follows: 我想这样做的原因如下:

I send a message to an actor which uses Slick 3 to query a database. 我向使用Slick 3查询数据库的actor发送消息。 The Slick query returns list: Future[List[T]] . Slick查询返回list: Future[List[T]] If I could convert this list to list: List[Future[T]] , then I would be able to do: 如果我可以将此list转换为list: List[Future[T]] ,那么我将能够:

list.map(convertToMessage).foreach(m => m pipeTo sender())

So basically I want to convert each record extracted from the DB into a message and then send it to a calling actor. 所以基本上我想将从DB中提取的每条记录转换成一条消息,然后将其发送给一个调用actor。

I don't think this is possible, sorry. 抱歉,我不认为这是可能的。

A Future[List[T]] could complete with an empty list, a list with one element, or any number of elements. Future[List[T]]可以用空列表,包含一个元素的列表或任意数量的元素来完成。

So if you converted it to a List[Future[T]] , how many Futures would the list contain? 因此,如果您将其转换为List[Future[T]] ,该列表将包含多少个Futures?

instead of using akkas pipeTo pattern, you can just do something like: 而不是使用akkas pipeTo模式,你可以做类似的事情:

// capture the sender, before the future is started - just like pipeTo does
val s = sender()
futureOfListOfFoo.foreach { listOfFoo =>
  listOfFoo.map(convertToMessage).foreach { foo => s ! foo }
}

Why do you want to do this? 你为什么要这样做? What do you want to achieve? 你想达到什么目的? As soon as your future resolves, all of the items in the list are available so you gain little by lifting each of them into its own future. 一旦您的未来结算,列表中的所有项目都可用,因此您可以通过将每个项目提升到自己的未来而获得很少的收益。

Anyway: 无论如何:

import scala.concurrent._
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global

// Assuming some starting future.
val foo: Future[List[String]] = Future.successful(List("foo"))

// This is pointless, because all we're doing is lifting each item in the list into its own already resolved future.
val bar: Future[List[Future[String]]] = foo.map(_.map(Future.successful))

// NB: you shouldn't use Await.
val baz: List[Future[String]] = Await.result(bar, 0.nanos)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM