2017-08-29 2 views
-1

J'ai été frappé par un morceau sur la façon d'obtenir un listbuffer de chaînes dans le cas où le listbuffer se trouve être construit dans un futur scala appelé en boucle.make scala future attente pour modifier une variable

Voici un exemple baiser

def INeedThatListBuffer(): ListBuffer[String] = { 

    var myCollections: ListBuffer[String] = new ListBuffer[String]() 

    for (day <- daysInaWeek) { 

    val myFuture: Future[String] = Future { 
     // use 'day' do some stuff and get me a result 
     ??? 
    } 

    myFuture.onComplete { 
     case Success(result) => 
     myCollections += result 

    } 
    } 

    myCollections 
} 

Mon problème est que listBuffer est parfois liste vide et parfois le contenu que je m'y attendais. Clairement, cette méthode est complète avant que le futur ne soit évalué.

Juste pour ajouter

  1. Je ne veux pas utiliser future.await
  2. En passant myCollections Future obj ne fonctionne pas comme il n'y a pas obligatoire que myFuture doit être complète avant myCollections est évaluée.

Veuillez m'aider.

Merci

+0

Est-ce que 'myFuture' doit retourner un' Future'? Si vous ne voulez pas utiliser 'Future.await' ou retourner un' Future', je ne vois aucune autre option. – adrice727

Répondre

3

Cela renvoie un future. Si vous ne vous souciez pas attendre qu'il soit complet, vous pouvez toujours accéder à la valeur sous-jacente à l'aide .value:

def INeedThatListBuffer(): Future[ListBuffer[String]] = { 

    def buildFutureFromDay(day: String): Future[String] = Future { ??? } 

    Future 
    .sequence(daysInAWeek.map(buildFutureFromDay)) 
    .map(_.foldLeft(ListBuffer[String]())(_ += _)) 

} 
+0

BTW vous pouvez utiliser la méthode '_.to [ListBuffer]' au lieu de '_.foldLeft (...)'. –

1

Vous devez await à un moment donné. Soit await pour chacun des contrats à terme pour être résolus ou changer le ListBuffer[String] en ListBuffer[Future[String]] et await sur le tampon entier plus tard.

val myFutureCollection: ListBuffer[Future[String]] = new ListBuffer[Future[String]]() 
val myFuture: Future[String] = Future(???) 

myFutureCollection += myFuture 

val eventualBuffer: Future[ListBuffer[String]] = Future.sequence(myFutureCollection) 
val buffer: ListBuffer[String] = Await.result(eventualBuffer, 2 seconds) 

P.S: Vous pouvez val au lieu de var pour le tampon de liste comme il est déjà mutable.