我如何等待Scala future的onSuccess回调完成? [英] How do I wait for a Scala future's onSuccess callback to complete?

查看:715
本文介绍了我如何等待Scala future的onSuccess回调完成?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Scala中,我可以使用 Await 等待将来的完成。但是,如果我已经注册了在将来完成时运行的回调,那么我不仅要等待将来完成,而且还要等待回调完成吗?

In Scala, I can use Await to wait for a future to complete. However, if I have registered a callback to run upon completion of that future, how can I wait not only for the future to complete but also for that callback to finish?

以下是一个最小但完整的程序来说明问题:

Here is a minimal but complete program to illustrate the problem:

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.Duration
import scala.concurrent.{ Await, Future }

object Main {
  def main(args: Array[String]): Unit = {
    val f: Future[Int] = Future(0)
    f.onSuccess { case _ =>
      Thread.sleep(10000)
      println("The program waited patiently for this callback to finish.")
    }

    // This waits for `f` to complete but doesn't wait for the callback
    // to finish running.
    Await.ready(f, Duration.Inf)
  }
}

我希望输出为:

The program waited patiently for this callback to finish.

相反,没有输出;

请注意,这与等待将来完成不一样,之前已经在这个问题

Please note that this is not the same problem as waiting for a future to complete, which has been answered previously at this question.

推荐答案

不要使用onSuccess回调,而是在Future.map调用中产生副作用。这样,您就可以使用Future [Unit]。

Don't use an onSuccess callback, but instead do the side effect in a Future.map call. That way, you have a Future[Unit] to use Await on.

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.Duration
import scala.concurrent.{ Await, Future }

object Main {
  def main(args: Array[String]): Unit = {
    val f: Future[Int] = Future(0)
    val f2: Future[Unit] = f.map { x =>
      Thread.sleep(10000)
      println("The program waited patiently for this callback to finish.")
    }

    Await.ready(f2, Duration.Inf)
  }
}

请注意,如果要执行边仅在成功的情况下才有效(例如您的示例),请使用map。如果您还想在发生故障的情况下执行副作用,则使用正确的方法。在scala-user上查看Roland Kuhn的帖子

Note that if you want to execute a side effect only in case of success (like in your example), map is appropriate. If you want to execute a side effect also in case of failure, andThen is the right method to use. See this post from Roland Kuhn on scala-user.

另外,请 不要 在生产代码附近的任何地方使用Thread.sleep。

Also, please don't use Thread.sleep anywhere near production code.

这篇关于我如何等待Scala future的onSuccess回调完成?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆