Eduardo
Eduardo

Reputation: 7141

While Loop with Futures in Scala

I have two methods:

def getNextJob: Future[Option[Job]]

def process(job: Job): Future[Unit]

I would like to process all Jobs until there are no jobs remaining.

I can do this with Await e.g.

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()
  }

But this is ugly and doesn't use Futures properly. Is there a way I could chain the futures somehow to replace this?

Upvotes: 1

Views: 2420

Answers (2)

Viktor Klang
Viktor Klang

Reputation: 26579

def processAll()(implicit ec: ExecutionContext): Future[Unit] =
  getNextJob.flatMap {
    case Some(job) => process(job).flatMap(_ => processAll())
    case None => Future.unit
  }

To process them all possibly concurrently:

def processAll()(implicit ec: ExecutionContext): Future[Unit] =
  getNextJob.flatMap {
    case Some(job) => process(job).zipWith(processAll())((_,_) => ())
    case None => Future.unit
  }

Upvotes: 3

Pritam Kadam
Pritam Kadam

Reputation: 2527

def go()(implicit ctx: ExecutionContext): Future[Unit] =
  getNextJob.flatMap { maybeJob ⇒
    if(maybeJob.isDefined) process(maybeJob.get).flatMap(_ ⇒ go())
    else Future.unit
  }

Note: It is not tail recursive.

Upvotes: 4

Related Questions