scala Future.序列的反转

uemypmqf  于 2023-06-06  发布在  Scala
关注(0)|答案(4)|浏览(165)

我知道Future.sequence调用可以将List[Future[T]]转换为Future[List[T]],但如果我想反过来呢?
我想把一个Future[List[T]]转换成一个List[Future[T]]
我想这样做的原因如下:
我发送一条消息给一个使用Slick3查询数据库的演员。Slick查询返回list: Future[List[T]]。如果我可以将这个list转换为list: List[Future[T]],那么我就可以做到:

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

因此,基本上我想将从DB中提取的每条记录转换为消息,然后将其发送给调用参与者。

13z8s7eq

13z8s7eq1#

我不认为这是可能的,对不起。
一个Future[List[T]]可以用一个空列表、一个包含一个元素的列表或任意多个元素的列表来完成。
如果你把它转换成List[Future[T]],那么这个列表会包含多少个Futures?

e5nszbig

e5nszbig2#

而不是使用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 }
}
b09cbbtk

b09cbbtk3#

你为什么要这么做?你想达到什么目的?一旦你的未来解决了,列表中的所有项目都是可用的,所以你通过将它们中的每一个提升到自己的未来中来获得很少。
总之:

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)
ltskdhd1

ltskdhd14#

我找不到Future.InverseSequence,但这可能是一个实现。

def inverseSequence[A](future: Future[Seq[A]])(implicit ec: ExecutionContext): Seq[Future[A]] = 
  future.flatMap(seq => Future.traverse(seq)(Future.successful))

相关问题