Considere el siguiente fragmento de código:

En esto, estoy tratando de obtener valores del futuro utilizando la comprensión 'For - yield'. Ahora en el método de rendimiento, necesito hacer una verificación que hace que la llamada a una función fallbackResult que devuelve un futuro y, por lo tanto, el tipo de retorno de getData se convierte en 'Futuro [Futuro [Opción [Int]]]' en lugar de 'Futuro [Opción [Int ]] '. ¿Cómo podría hacer esto de una mejor manera? (Utilicé Map & FlatMap, pero el código es poco feo debido a la anidación de Maps y 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
}
0
user3635344 20 mar. 2017 a las 19:26

2 respuestas

La mejor respuesta

Pondría el código dentro de la comprensión:

for {
   substanceTable <- substanceTableF
   mixtureTable <- mixtureTableF 
   result <- {
     if (substanceTable.isEmpty && mixtureTable.isEmpty)
       fallbackResult()
     else
       Future.successful(Some(100))
   }
 } yield result
0
Vidya 20 mar. 2017 a las 22:38

Hay muchas maneras de manejar esto, pero la clave es mover su lógica yield a su comprensión for. Una forma de hacerlo es la siguiente:

for {
  substanceTable <- substanceTableF
  mixtureTable <- mixtureTableF
  result <- (substanceTable.headOption orElse mixtureTable.headOption)
               .map(_ => Future.successful(Some(100)))
               .getOrElse(fallbackResult)
} yield result
1
Vidya 20 mar. 2017 a las 22:33