我有一个外部未来操作,我可以覆盖它的onOperation完成方法。我想通过关闭 Promise 来包装它并完成。但是,在其他未来,我无法完成未来。例如:
import scala.concurrent.{Future, Promise}
import scala.util.{Failure, Success}
import scala.concurrent.ExecutionContext.Implicits.global
def foo():Future[String] = {
val p = Promise[String]()
channel.addListener(new ChannelFutureListener[IoReadFuture] {
override def operationComplete(future: IoReadFuture): Unit = {
p.success("hello")}
}
p.future
}
val x = foo()
x: scala.concurrent.Future[String] = List()
x.onComplete{
case Success(msg) => println(s"$msg world")
case Failure(e) => println(e.getMessage)
}
res1: Unit = ()
是否有惯用的方法不阻止?
答案 0 :(得分:0)
我认为您正在尝试创建一个以delay
作为输入并返回delayed future
的函数。
如果您想这样做,可以使用Await
和Promise
以非睡眠的方式执行此操作。
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.{Future, Promise}
import scala.concurrent.duration._
// returns a future delayed by `delay` seconds
def getDelayedFutureOfStringValue(delay: Int, value: String): Future[String] = {
// we will use this promise for wait only
val waitProxyPromise = Promise[Int]()
val delayedFuture = Await.ready(waitProxyPromise.future, delay.second).map({
case _ => value
})
delayedFuture
}
val helloFuture = getDelayedFutureOfStringValue(2, "hello")
上面的amy看起来像是一个不错的实现,但实际上并非如此。 Await
实际上阻止了该线程。可悲的是......在惯用的Scala中,以一种完全无阻塞的方式获取delayedFutue并不容易。
使用Java中的Timer实用程序
可以获得一个很好的非阻塞和非睡眠延迟的未来import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.{Future, Promise}
import java.util.{Timer, TimerTask}
// delay is number of seconds
def getDelayedFutureOfStringValue(delay: Int, value: String): Future[String] = {
val promise = Promise[String]()
val timer = new Timer()
val timerTask = new TimerTask {
override def run(): Unit = promise.success(value)
}
timer.schedule(timerTask, delay * 1000)
promise.future
}
val niceHelloFuture = getDelayedFutureOfStringValue(2, "hello")
如果你已经和你有了未来,而你想用它来构建一个依赖的未来,那么它很容易。
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.{Future, Promise}
import scala.util.{Failure, Success}
// I assume you IoReadFuture is either similar to Future or wraps the actual Future
def foo(value: String):Future[String] = {
val p = Promise[String]()
channel.addListener(new ChannelFutureListener[IoReadFuture] {
override def operationComplete(ioFuture: IoReadFuture): Unit = {
ioFuture.future.onComplete(_ => p.success(value))
}
}
p.future
}
答案 1 :(得分:0)
scheduleOne
是阻塞某些代码执行的非阻塞方式
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext
import ExecutionContext.Implicits.global
val p = Promise(doSomething())
val system = akka.actor.ActorSystem("system")
system.scheduler.scheduleOne(deplay seconds)(p.future)
val f = p.future
f.flatMap { println(s"${_}") }