Scala waiting for sequence of futures

后端 未结 6 2318
野的像风
野的像风 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:10

    We can enrich Seq[Future[T]] with its own onComplete method through an implicit class:

      def lift[T](f: Future[T])(implicit ec: ExecutionContext): Future[Try[T]] =
        f map { Success(_) } recover { case e => Failure(e) }
    
      def lift[T](fs: Seq[Future[T]])(implicit ec: ExecutionContext): Seq[Future[Try[T]]] =
        fs map { lift(_) }
    
      implicit class RichSeqFuture[+T](val fs: Seq[Future[T]]) extends AnyVal {
        def onComplete[U](f: Seq[Try[T]] => U)(implicit ec: ExecutionContext) = {
          Future.sequence(lift(fs)) onComplete {
            case Success(s) => f(s)
            case Failure(e) => throw e // will never happen, because of the Try lifting
          }
        }
      }
    

    Then, in your particular MWE, you can do:

      val f1 = Future {
        throw new Throwable("baaa") // emulating a future that bumped into an exception
      }
    
      val f2 = Future {
        Thread.sleep(3000L) // emulating a future that takes a bit longer to complete
        2
      }
    
      val lf = List(f1, f2)
    
      lf onComplete { _ map {
        case Success(v) => ???
        case Failure(e) => ???
      }}
    

    This solution has the advantage of allowing you to call an onComplete on a sequence of futures as you would on a single future.

提交回复
热议问题