Scala waiting for sequence of futures

后端 未结 6 2312
野的像风
野的像风 2020-12-04 15:39

I was hoping code like follows would wait for both futures, but it does not.

object Fiddle {
  val f1 = Future {
    throw new Throwable(\"baaa\") // emulat         


        
6条回答
  •  一向
    一向 (楼主)
    2020-12-04 16:16

    One common approach to waiting for all results (failed or not) is to "lift" failures into a new representation inside the future, so that all futures complete with some result (although they may complete with a result that represents failure). One natural way to get that is lifting to a Try.

    Twitter's implementation of futures provides a liftToTry method that makes this trivial, but you can do something similar with the standard library's implementation:

    import scala.util.{ Failure, Success, Try }
    
    val lifted: List[Future[Try[Int]]] = List(f1, f2).map(
      _.map(Success(_)).recover { case t => Failure(t) }
    )
    

    Now Future.sequence(lifted) will be completed when every future is completed, and will represent successes and failures using Try.

    And so, a generic solution for waiting on all original futures of a sequence of futures may look as follows, assuming an execution context is of course implicitly available.

      import scala.util.{ Failure, Success, Try }
    
      private def lift[T](futures: Seq[Future[T]]) = 
        futures.map(_.map { Success(_) }.recover { case t => Failure(t) })
    
      def waitAll[T](futures: Seq[Future[T]]) =
        Future.sequence(lift(futures)) // having neutralized exception completions through the lifting, .sequence can now be used
    
      waitAll(SeqOfFutures).map { 
        // do whatever with the completed futures
      }
    

提交回复
热议问题