11
votes

transformer un SEQ [futur [x]] dans un énumérateur [x]

Y a-t-il un moyen de transformer un SEQ [futur [x]] en un Future Select Gist pourrait être utilisé pour le faire - bien qu'il soit assez inefficace.

Remarque: les itérations et l'énumérateur en question sont ceux donnés par la version de jeu version 2.x, c'est-à-dire avec les importations suivantes: importer play.api.libs.iterate ._


0 commentaires

7 Réponses :


3
votes

Utilisation de Méthode de sélection de Victor Klang : xxx

je peux alors obtenir ce dont j'ai besoin avec xxx


1 commentaires

Je suis un peu préoccupé que l'utilisation de la mise en œuvre de Victor Klang n'est pas suffisamment efficace. Dans cet algorithme, nous devons traverser toute la séquence, ce qui nécessite chaque avenir d'être enregistré avec une nouvelle promesse de chaque passage. Il devrait être possible de créer un algorithme où il suffit de le faire une seule fois ... Peut-être que c'est juste une question d'énumérateur de sous-classement et d'enregistrer chaque avenir dans la séquence avec l'énumérateur.



0
votes

Vous pouvez construire un à l'aide du service Java Executor Computer Service ( Javadoc ). L'idée est d'utiliser Créer une séquence de nouveaux contrats à terme, chacune à l'aide de ExecutorCleService.take () pour attendre le résultat suivant. Chaque avenir commencera, lorsque l'avenir précédent a son résultat.

Mais s'il vous plaît b e conscience, que cela pourrait ne pas être aussi efficace, car beaucoup de synchronisation se produisent dans les coulisses. Il peut être plus efficace d'utiliser une carte parallèle réduite pour le calcul (par exemple à l'aide de Scala's Parseq) et laissez l'énumérateur à attendre le résultat complet.


1 commentaires

«Chaque avenir commencera lorsque l'avenir précédent a un résultat»: cela semble être bloqué. Dans le code fourni dans ma réponse ci-dessus tous les contrats à terme dans le SEQOFTURESA est exécuté en parallèle.



2
votes

Une réponse plus belle, plus courte et je pense que la réponse plus efficace est la suivante: xxx


2 commentaires

Attention, futur. / code> renvoie un avenir échoué si l'un des SEQFuTUREX échoue à terme.


Et ces solutions attendent tous les contrats à terme avant de nourrir ITEREE, tandis qu'un autre de @BBlfish le placé le plus tôt possible (sans ordre préservé!).



0
votes

AVERTISSEMENT: Non compilé Avant de répondre

Qu'en est-il de quelque chose comme ceci: xxx


3 commentaires

La signature du pli est def pli [t, r] (contrats à terme: scala.traversionAnconce [futur [t]]) (zéro: r) (pliFun: (r, t) => r) (exécuteur implicite: exécutionContext ): Futur [r] mais votre code a la signature pli [t, r] (contrats à terme: SEQ [Future [T]]) (zéro: ITEREE [T, R]) (FIXFUN: R, t) => futur [r]) (exécuteur implicite: exécutionContext): futur [r] Il y a un problème avec FLIGFUN, car i.flatmap (_. Flux (x) ) renvoie un futur [r] pas un r


Mais je suis de type "ITEREE [X, A]" et Flatmap devrait renvoyer une "ITEREE [X, A]", non? (étant donné que l'alimentation retourne iTRETE [x, a])


Lecture iTEREE [E, A] définit plattmap comme: def platmap [B] (F: A => ITEREE [E, B]): itérale [e , B] de sorte que votre cas soit vraiment écrit comme cas (i, x) => i.flatmap (a => ...) . Et ensuite A n'est plus un iTEREE , et il n'a donc pas de méthode (code> (code>. Si, d'autre part, on essaie alors de faire case (i, x) => i flux (INPUT.EL (x)) alors on finit par un terme avec un futur [. .]] ce qui n'est pas quel pli veut. La grande chose est que sans le système de type Scala, je ne pense pas que j'aurais jamais trouvé la réponse ... :-)



0
votes

Voici quelque chose que j'ai trouvé utile, xxx


0 commentaires

1
votes

Je me rends compte que la question est déjà un peu ancienne, mais basée sur la réponse de Saintehosh et l'Enumterator intégré.Numérer () Mise en œuvre que j'ai proposée avec ce qui suit:

// For lack of a better name
def mapEachM[E, NE](eventuallyList: Future[List[E]])(f: E => Future[NE])(implicit ec: ExecutionContext): Enumerator[NE] =
  Enumerator.flatten(
    eventuallyList map { list =>
      enumerateM(list map f)
    }
  )


0 commentaires

0
votes

Je voudrais proposer l'utilisation d'une émission

def seqToEnumerator[A](futuresA: Seq[Future[A]])(defaultValue: A, errorHandler: Throwable => A): Enumerator[A] ={
    val (enumerator, channel) = Concurrent.broadcast[A]
    futuresA.foreach(f => f.onComplete({
      case Success(Some(a: A)) => channel.push(a)
      case Success(None) => channel.push(defaultValue)
      case Failure(exception) => channel.push(errorHandler(exception))
    }))
    enumerator
  }


0 commentaires