2017-06-27 3 views
2

zu implementieren habe ich eine Methode:Wie Futures Zusammensetzung

def findUserById(id: String): Future[Option[User]] 

Jetzt möchte ich eine andere Methode machen, basierend darauf:

def findUserById(ids: Seq[String]): Future[Seq[User]] 

Aber ich habe ein Problem mit Futures. Wie man die Futures-Zusammensetzung richtig implementiert?

Ich habe eine Implementierung (nicht getestet), aber ich denke, es kann einfacher gemacht werden. Auch ich bin nicht sicher über die Leistung dieser Umsetzung:

override def findUsersById(ids: Seq[String]): Future[Seq[User]] = { 
    val futures = ids.map(id => findUserById(id)) 
    val filtered = Future.sequence(futures).map(_.filterNot(_.isEmpty)).map(_.map(_.get)) 
    filtered 
    } 

Antwort

5

Sie können ersetzen sequence + map mit traverse und filter + map mit flatten:

def findUsersById(ids: Seq[String]): Future[Seq[User]] = 
    Future.traverse(ids)(findUserById).map(_.flatten) 

Im Allgemeinen Future.traverse ist prägnanter als Future.sequence , und ist ein bisschen effektiver, weil es vermeidet, ein Zwischenprodukt Seq[Future[T]] zu erstellen.

+0

Sekunden zu spät: D – thwiegan

+0

Können Sie bitte auch die "Leistung dieser Implementierung" erklären? Eine kurze Beschreibung darüber, wie Future in diesem Fall funktioniert, wäre sehr hilfreich. – oblivion

+0

@oblivion Es tut mir leid, ich verstehe nicht, was Sie über die Leistung wissen wollen und wie Future funktioniert. Was die Performance betrifft, ist dies wahrscheinlich einer der effektivsten Ansätze, die man mit 'Future's machen kann (es ist auch möglich, die letzte' map' zu entfernen, aber ich denke, es ist zu viel Code für einen kleinen Gewinn). – Kolmar