Scala - Future List first completed with condition

2019-07-04 11:40发布

I have a list of Futures and I want to get the first one completed with a certain condition. Here is an example of a possible code:

val futureList: Future[List[T]] = l map (c => c.functionWithFuture())
val data = for {
           c <- futureList
           }yield c
data onSuccess {
  case x => (x filter (d=> d.condition)).head
}

But it's not efficient, because I'll take only one element of the list, but computed all of them with a lot of latency.

I know firstCompletedOf but it's not what I'm searching.

(Sorry for my bad English.)

1条回答
迷人小祖宗
2楼-- · 2019-07-04 12:21

Try using a Promise and calling trySuccess on it as soon as a future that satisfies the condition completes. The first to call trySuccess will complete the future, the following ones will have no effect (as opposed to calling success, which can only be called once on a Promise).

Keep in mind that if no future in the list satisfies the condition, you will never have a result, i.e. the promise future will never complete.

import scala.concurrent.{ Await, Future, Promise }
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.util.Random

def condition(x: Int) = x > 50

val futures = (1 to 10) map (x => Future {
  // wait a random number of ms between 0 and 1000
  Thread.sleep(Random.nextInt(1000))
  // return a random number < 100
  Random.nextInt(100)
})

val p = Promise[Int]()
// the first one that satisfies the condition completes the promise
futures foreach { _ filter condition foreach p.trySuccess }
val result = p.future

// Watch out: the promise could never be fulfilled if all the futures are <=50
println("The first completed future that satisfies x>50 is: " + Await.result(result, 10.seconds))
查看更多
登录 后发表回答