Tengo un problema al encadenar 2 futuros juntos, lo que me gustaría hacer es lo siguiente:

import scala.concurrent.{ ExecutionContext, Future } 

 def lastFiveFullNews: Future[Seq[FullNews]] = {
  for (
  seq <- getLastFiveNews;
  news <- seq;
  fullNews <- getFullNewsById(news.id) //error at this line

) yield fullNews
}

Con las siguientes firmas de método:

def getLastFiveNews: Future[Seq[News]]
def getFullNewsById(id: Long): Future[FullNews]
def lastFiveFullNews: Future[Seq[FullNews]]

Básicamente, un FullNews se genera con un ID de News. En el editor de Idea no se informa ningún error, pero el compilador de reproducción dice:

desajuste de tipos; encontrado: scala.concurrent.Future [FullNews] requerido: scala.collection.GenTraversableOnce [?]

Creo que esto no funciona porque en el bucle for no solo hay Futures de scala, sino también Seq. Pero sin el Seq no sé cómo escribirlo. Algunas ideas ? Gracias.

1
f7h 13 ene. 2017 a las 01:44

1 respuesta

La mejor respuesta

Como sospecha, no puede mezclar diferentes mónadas en una comprensión. Ya que está trabajando con Future s, todas las líneas en la for-comprensión deben producir Future s. Puede usar Future.sequence, que convertirá un Seq[Future[...]] en un Future[Seq[...]]:

def lastFiveFullNews: Future[Seq[FullNews]] = {
  for (
    seq <- getLastFiveNews
    fullNews <- Future.sequence(
      seq.map(news => getFullNewsById(news.id))
    )
  ) yield fullNews
}
5
Alvaro Carrasco 13 ene. 2017 a las 01:59
También puede usar Future.traverse combinando Future.sequence y Seq#map: Future.traverse(seq)(news => getFullNewsById(news.id)).
 – 
Peter Neyens
13 ene. 2017 a las 16:11