1

我正在使用 akka 数据流,我想知道是否有一种方法可以使特定的代码块等待未来的完成,而无需明确使用该未来的值。

实际用例是我有一个文件,我希望在特定的未来完成时删除该文件,但不是在此之前。这是一个粗略的例子。首先想象我有这个服务:

trait ASync {
   def pull: Future[File]
   def process(input : File): Future[File]
   def push(input : File): Future[URI]
}

我有一个我想以非阻塞方式运行的工作流程:

val uriFuture = flow {
    val pulledFile = async.pull(uri)
    val processedile = async.process(pulledFile())
    val storedUri = async.push(processedFile())

    // I'd like the following line executed only after storedUri is completed, 
    // not as soon as pulled file is ready.
    pulledFile().delete()

    storedUri()
}
4

2 回答 2

1

你可以尝试这样的事情:

val uriFuture = flow {
  val pulledFile = async.pull(uri)
  val processedile = async.process(pulledFile())
  val storedUri = for(uri <- async.push(processedFile())) yield {
    pulledFile().delete()
    uri
  }
  storedUri()
}

在这个例子中,只有在from成功pulledFile.delete时才会被调用。如果失败,将不会被调用。未来的结果仍将是调用的结果。FuturepushdeletestoredUripush

或者另一种方式是:

val uriFuture = flow {
  val pulledFile = async.pull(uri)
  val processedile = async.process(pulledFile())
  val storedUri = async.push(processedFile()) andThen{
    case whatever => pulledFile().delete()
  }
  storedUri()
}

这里的区别在于delete无论push成功还是失败都会被调用。still 的结果storedUri将是调用的结果push

于 2013-05-26T22:43:06.280 回答
0

您可以将回调用于非阻塞工作流程:

future onSuccess {
  case _ => file.delete() //Deal with cases obviously... 

}

来源:http ://doc.akka.io/docs/akka/snapshot/scala/futures.html

或者,您可以使用 Await.result 阻止:

val result = Await.result(future, timeout.duration).asInstanceOf[String]

后者通常在您需要阻塞时使用 - 例如在测试用例中 - 而非阻塞性能更高,因为您不会停放线程以启动另一个线程只是为了再次恢复另一个线程 - 这比异步活动慢,因为的资源管理开销。

类型安全的工作人员称其为“反应式”。这是一个小流行语。如果您在工作场所使用它,我会笑。

于 2013-06-02T14:48:34.130 回答