gpt4 book ai didi

scala - 在 Scala 工作表中打印 Futures 的结果

转载 作者:行者123 更新时间:2023-12-02 16:46:05 26 4
gpt4 key购买 nike

我正在 Coursera 上学习响应式编程类(class),在做其中一项作业时,我遇到了一些奇怪的事情。不管怎样,我通过这个扩展向 Future Companion 对象添加了一些方法

implicit class FutureCompanionOps[T](val f: Future.type) extends AnyVal {

/** Returns a future that is always completed with `value`.
*/
def always[T](value: T): Future[T] = Future(value)

/** Returns a future that is never completed.
*
* This future may be useful when testing if timeout logic works correctly.
*/
def never[T]: Future[T] = Promise().future


/** Given a list of futures `fs`, returns the future holding the list of values of all the futures from `fs`.
* The returned future is completed only once all of the futures in `fs` have been completed.
* The values in the list are in the same order as corresponding futures `fs`.
* If any of the futures `fs` fails, the resulting future also fails.
*/
def all[T](fs: List[Future[T]]): Future[List[T]] = {
val resPr = Promise[List[T]]()
def function( in: List[Future[T]], fxs:Future[List[T]] ): Future[List[T]] =
{
if(in.isEmpty) fxs
else
function( in.tail, for { i <- in.head ; xs <- fxs } yield { i :: xs } )
}
function( fs, resPr.success(Nil).future )
}
}

然后我在 Eclipse 中的 Scala WorkSheet 上写了这个

object TestSheet {

val tempPr = Promise[Boolean]()
val anotherFuLs = List( Future.always(true), Future.always(false), tempPr.future )
//> anotherFuLs : List[scala.concurrent.Future[Boolean]] = List(scala.concurren
//| t.impl.Promise$DefaultPromise@a19b1de, scala.concurrent.impl.Promise$Default
//| Promise@1cec6b00, scala.concurrent.impl.Promise$DefaultPromise@625dcec6)
val crapFut = Future.all(anotherFuLs) //> crapFut : scala.concurrent.Future[List[Boolean]] = scala.concurrent.impl.Pr
//| omise$DefaultPromise@6564dbd5
crapFut.isCompleted //> res3: Boolean = false
tempPr.success(false) //> res4: nodescala.TestSheet.tempPr.type = scala.concurrent.impl.Promise$Defaul
//| tPromise@625dcec6
crapFut.isCompleted //> res5: Boolean = true
crapFut onComplete {
case Success(ls) => println( ls )
case Failure(e) => println( "Failed with Exception " + e )
}
}

无论如何,我都无法让 Scala 工作表打印出结果列表的值。然而,当我编写单元测试并运行 scala 测试时,比较最终结果列表没有问题。这是处理异步内容时 scala 工作表中的错误吗?

这是单元测试

test("A composed future with all should complete when all futures complete") {
val tempPr = Promise[Boolean]()
val lsFu = List( Future.always(true), Future.always(false), tempPr.future );
val fuL = Future.all( lsFu )
fuL onComplete { case Success(ls) => println( "This got done" ); assert( ls === List( true, false, true ), "I should get back the expected List" )
case Failure(ex) => assert( false, "Failed with Exception " + ex ) }
assert( fuL.isCompleted === false, "The resulting Future should not be complete when the depending futures are still pending" )
tempPr.success(true)

}

最佳答案

看起来问题是运行工作表代码的主线程在 onComplete 处理程序运行之前结束。

Scala 的默认 ExecutionContext 本质上是一个充满守护线程的线程池。在这种情况下,“守护进程”意味着即使该线程正忙于执行某些操作,它也不会阻止 JVM 在所有非守护线程完成时关闭。在您的情况下,主线程可能是程序中唯一的非守护线程。

对 Future 调用 onComplete 将使隐式提供的 ExecutionContext 在 Future 完成时执行您的处理程序。这意味着处理程序在守护线程上运行。由于 onComplete 是您在 main 方法中执行的最后一件事,因此 JVM 只是在 ExecutionContext 开始运行处理程序之前完成。

通常情况下,这没什么大不了的。在像 Web 服务器这样的场景中,您的 JVM 将启动并运行很长一段时间。对于您的用例,我建议使用 scala.concurrent.Await 中的方法之一来阻止 Future 完成。这样您就可以在 main 方法中将完成逻辑作为主线程的一部分运行。

关于scala - 在 Scala 工作表中打印 Futures 的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20821398/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com