在Future中的阻塞是否仍然会阻塞?

3

阻塞是不好的,异步是好的,但在一个future中进行阻塞是否仍然会阻塞?这是我一直在思考的问题;请考虑以下伪代码:

def queryName(id:Id):Future[String]
def queryEveryonesNames:Future[Seq[String]] = {
  val everyonesIds:Future[Seq[Id]] = getIds
  val everyonesNames:Future[Seq[Future[String]]] = {
    everyonesIds.map(seq.map(id=>queryName(id)))
  }
  // I'm trying to understand the impact of what I'll do below
  everyonesNames.map(seq=>seq.map(fut=>blocking(fut, 1 s)))
}
queryEveryonesNames

在最后一行代码中,我通过阻塞内部的FutureFuture [Seq [Future [String]]](注意Future内嵌)转换为Future [Seq [String]]
在这里,阻塞内部Future似乎是多余的,但是内嵌Future也是多余的。
您能否提出一种更聪明的方法来消除内部的Future?
您认为在Future内部阻塞Future是不好的吗?如果是,为什么?在什么情况下?
1个回答

8

是的,未来阻塞是阻塞的,您应该避免这种情况,因为资源将被阻塞以等待结果,即使它们在另一个线程中。


如果我理解正确,您的问题是如何以非阻塞的方式将Future [Seq [Future [String]]]转换为Future [Seq [String]]

您可以使用for循环实现:

val in =  Future[Seq[Future[String]]]
val m = for( a <- in ) // a is Seq[Future[String]]
yield ( Future.sequence(a)) // yields m = Future[Future[Seq[String]]]
val result = for(a <- m; b <- a) yield (b) // yields Future[Seq[String]]

编辑: 或者简单点:

val result = in.flatMap(a => Future.sequence(a))

2
你只需要使用 in.flatMap( Future.sequence ) 就可以得到相同的结果。 - paradigmatic
Future 伴生对象有一些非常有用的方法,感谢介绍。干杯! - Dominykas Mostauskis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接