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. p>
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 ._ code> p> p>
7 Réponses :
Utilisation de Méthode de sélection de Victor Klang :
je peux alors obtenir ce dont j'ai besoin avec
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.
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 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. P> ExecutorCleService.take () code> pour attendre le résultat suivant. Chaque avenir commencera, lorsque l'avenir précédent a son résultat. P>
«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 code> est exécuté en parallèle.
Une réponse plus belle, plus courte et je pense que la réponse plus efficace est la suivante:
Attention, futur. / code> renvoie un avenir échoué si l'un des
SEQFuTUREX code> é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é!).
AVERTISSEMENT: Non compilé Avant de répondre
Qu'en est-il de quelque chose comme ceci: p>
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] code> 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] code> Il y a un problème avec FLIGFUN, car
i.flatmap (_. Flux (x) ) code> renvoie un
futur [r] code> pas un
r code>
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] code> définit
plattmap code> comme:
def platmap [B] (F: A => ITEREE [E, B]): itérale [e , B] code> de sorte que votre cas soit vraiment écrit comme cas
(i, x) => i.flatmap (a => ...) code>. Et ensuite
A code> n'est plus un
iTEREE code>, et il n'a donc pas de méthode code> (code> (code>. Si, d'autre part, on essaie alors de faire
case (i, x) => i flux (INPUT.EL (x)) code> alors on finit par un terme avec un futur
[. .]] code> 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 ... :-)
Voici quelque chose que j'ai trouvé utile,
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) } )
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 }