Scala:处理从Yeild返回Future的更好方法,以避免未来的未来

时间:2017-03-20 16:26:57

标签: scala future yield

请考虑以下代码段:

在此,我试图从未来使用' For - yield'理解。现在在yield方法中,我需要做一个检查,它调用函数fallbackResult,它返回一个future,因此getData的返回类型变为' Future [Future [Option [Int]]]'而不是未来[Option [Int]]'。我怎么能以更好的方式做到这一点? (我确实使用了Map& FlatMap' s,但由于嵌套了Maps和FlatMaps,代码有点难看)

def getData(): Future[Future[Option[Int]]] = {

  /* These are two future vectors. Ignore the Objects */

  val substanceTableF: Future[Vector[OverviewPageTableRowModel]] = getSubstanceTable(substanceIds, propertyId, dataRange)
  val mixtureTableF: Future[Vector[OverviewPageTableRowModel]] = getMixtureTableForSubstanceCombination(substanceIds, propertyId, dataRange)

  /* I have put for yeild to get values from futures.*/
  for {
      substanceTable <- substanceTableF
      mixtureTable <- mixtureTableF
  } yield {
      if(substanceTable.isEmpty && mixtureTable.isEmpty) {
          val resultF = fallbackResult()
          resultF.map(result => {Some(result)})
      } else {
          Future.successful(Some(100))
      }
  }
}

private def fallbackResult(): Future[Int] = { 
    // This method returns future of int
}

2 个答案:

答案 0 :(得分:1)

有很多方法可以解决这个问题,但关键是将yield逻辑移到for理解中。一种方法如下:

for {
  substanceTable <- substanceTableF
  mixtureTable <- mixtureTableF
  result <- (substanceTable.headOption orElse mixtureTable.headOption)
               .map(_ => Future.successful(Some(100)))
               .getOrElse(fallbackResult)
} yield result

答案 1 :(得分:0)

我把代码放在for-corehension中:

for {
   substanceTable <- substanceTableF
   mixtureTable <- mixtureTableF 
   result <- {
     if (substanceTable.isEmpty && mixtureTable.isEmpty)
       fallbackResult()
     else
       Future.successful(Some(100))
   }
 } yield result