在 Scala 中使用 Futures 循环
While Loop with Futures in Scala
我有两个方法:
def getNextJob: Future[Option[Job]]
def process(job: Job): Future[Unit]
我想处理所有作业,直到没有作业剩余。
我可以用 Await
做到这一点,例如
private def process()(implicit ctx: ExecutionContext): Future[Unit] = {
var job: Option[Job] = Await.result(service.getNextJob, FiniteDuration(2, TimeUnit.SECONDS))
while(job.isDefined) {
Await.result(process(job.get), FiniteDuration(2, TimeUnit.SECONDS))
job = Await.result(service.getNextJob, FiniteDuration(2, TimeUnit.SECONDS))
}
Future.successful()
}
但这很丑陋并且没有正确使用 Futures。有什么办法可以用某种方式链接期货来取代它吗?
def go()(implicit ctx: ExecutionContext): Future[Unit] =
getNextJob.flatMap { maybeJob ⇒
if(maybeJob.isDefined) process(maybeJob.get).flatMap(_ ⇒ go())
else Future.unit
}
注意:不是尾递归
def processAll()(implicit ec: ExecutionContext): Future[Unit] =
getNextJob.flatMap {
case Some(job) => process(job).flatMap(_ => processAll())
case None => Future.unit
}
尽可能同时处理它们:
def processAll()(implicit ec: ExecutionContext): Future[Unit] =
getNextJob.flatMap {
case Some(job) => process(job).zipWith(processAll())((_,_) => ())
case None => Future.unit
}
我有两个方法:
def getNextJob: Future[Option[Job]]
def process(job: Job): Future[Unit]
我想处理所有作业,直到没有作业剩余。
我可以用 Await
做到这一点,例如
private def process()(implicit ctx: ExecutionContext): Future[Unit] = {
var job: Option[Job] = Await.result(service.getNextJob, FiniteDuration(2, TimeUnit.SECONDS))
while(job.isDefined) {
Await.result(process(job.get), FiniteDuration(2, TimeUnit.SECONDS))
job = Await.result(service.getNextJob, FiniteDuration(2, TimeUnit.SECONDS))
}
Future.successful()
}
但这很丑陋并且没有正确使用 Futures。有什么办法可以用某种方式链接期货来取代它吗?
def go()(implicit ctx: ExecutionContext): Future[Unit] =
getNextJob.flatMap { maybeJob ⇒
if(maybeJob.isDefined) process(maybeJob.get).flatMap(_ ⇒ go())
else Future.unit
}
注意:不是尾递归
def processAll()(implicit ec: ExecutionContext): Future[Unit] =
getNextJob.flatMap {
case Some(job) => process(job).flatMap(_ => processAll())
case None => Future.unit
}
尽可能同时处理它们:
def processAll()(implicit ec: ExecutionContext): Future[Unit] =
getNextJob.flatMap {
case Some(job) => process(job).zipWith(processAll())((_,_) => ())
case None => Future.unit
}