【问题标题】:How to track exceptions and results of nested futures in scala如何在scala中跟踪嵌套期货的异常和结果
【发布时间】:2020-08-12 03:29:18
【问题描述】:

我有一个场景,我想计算嵌套的期货。下面是场景:

def firstFuture(factor: Int): Future[Int] = Future {
    println("Running future 1")
    Thread.sleep(3000)
    5 * factor
  }

  def secondFuture(factor: Int) = Future {
    println("Running future 2")
    throw new Exception("fjdfj")
    Thread.sleep(4000); 3 * factor
  }

  def thirdFuture = Future {
    println("Running future 3")
    Thread.sleep(5000)
    throw new Exception("mai fat raha hu")
  }

  def method = {
    (Future(5).map { factor =>
      firstFuture(factor).recover { case ex: Exception => throw new Exception("First future failed") }
      secondFuture(factor).recover { case ex: Exception => throw new Exception("Second future failed") }
      thirdFuture.recover { case ex: Exception => throw new Exception("Third future failed") }
    }).flatMap(identity).recover { case ex: Exception =>
      println("Inside recover")
      println(ex.getMessage)
    }
  }
  Await.result(method, 20 seconds)

我想处理主要未来完成的所有嵌套未来的异常。假设如果 secondFuture 失败,那么结果应该是 secondFuture 失败。但我只是在第三个未来得到反映。我怎样才能做到这一点。应该如何实现。

注意:嵌套的三个期货应该并行运行。

【问题讨论】:

    标签: scala error-handling future


    【解决方案1】:

    你只得到第三个未来的错误的原因是因为整个块的值是块的最后一个表达式,所以

    Future(5).map { factor =>
      firstFuture(factor)   // this executes but the result is discarded
      secondFuture(factor)  // this executes but the result is discarded
      thirdFuture           // the last expression becomes the value of the whole block
    }
    

    还要考虑当我们嵌套了 future 并且我们将其放入一个内部 future 时会发生什么

    Future(41).map { v =>
      Future(throw new RuntimeException("boom"))  // the exception is simply swallowed
      v + 1                                      
    }
    

    结果是Future(42),尽管在内部Future 中抛出了异常。理解这一点很重要,否则我们可能会在系统中引入静默故障

    为了达到您的要求try for-comprehension 和Future.sequence 的组合

    for {
      factor <- Future(5)
      results <- Future.sequence(List(firstFuture(factor), secondFuture(factor), thirdFuture))
    } yield results
    

    传递给sequence 的三个future 将同时执行,如果其中任何一个失败,sequence 将返回一个失败的future。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-27
      • 2020-09-14
      • 2021-03-17
      • 2012-10-23
      • 1970-01-01
      • 2017-09-30
      • 2020-03-09
      • 1970-01-01
      相关资源
      最近更新 更多