J'ai deux futurs qui résolvent à booléens. Je veux fondamentalement faire quelque chose comme mais, avec l'optimisation que l'on se termine d'abord, si c'est vrai, je n'attends pas que le futur futur ait fini; juste aller. Bien sûr, si la valeur est fausse, attendez que le futur futur finisse. Y a-t-il une façon simple de faire cela? P> p>
4 Réponses :
Dans le cas général, vous pouvez donner la même promesse aux deux livraisons. Par exemple: appeler à votre cas spécifique, vous avez besoin de deux booléens être retournés. La seule chose que je puisse penser (et c'est un peu désordonnée) serait d'utiliser une troisième promesse partagée entre les livreurs: p> invoquer à plusieurs reprises (foo) code> donnera au hasard
: a code> ou
: b code> dès que le Premier
livrer code> se produit; L'autre
livrer code> sera un non-op. p>
A code> délivre
true code> d'abord, le
ou code> est terminé immédiatement. Li>
A code> délivre
false code> d'abord, le
@A code> retourne immédiatement, puis bloque sur
@b code>. < / li>
B code> délivre
true code> d'abord, le
ou code> est terminé immédiatement. LI>
a code> délivre
false code> d'abord, il bloque sur
@a code>. li>
ul>
(foo) code> et vous devez voir les résultats escomptés, en particulier lorsque
: ou code> est
vrai code>, alors parfois
: a? code> ou
: B? code> sera
FALSE code>, mais les deux seront toujours
true code> si
Si: ou code> est
false code>. p> p>
Merci pour l'effort, mais je ne pense pas non plus travailler dans ma situation - je n'ai pas accès au code qui appelle livrer code>. J'ai mis à jour la question pour que cela soit plus évident.
Le cas commun avec les contrats à terme est que vous souhaitez que les données de toutes, mais peuvent faire le travail en parallèle. Le court-circuit s'écarte de cela. Je suis enclin à dire simplement utiliser ou code>. L'exécution la plus courte sera lorsque le premier futur devienne
true code> avant le deuxième avenir terminé, l'exécution la plus longue sera lorsque le premier futur devienne
false code> et la seconde prend plus de temps pour Achevée.
J'adore cette question. Peut-être que je suis surpris que de voir une nouvelle question qui est si simple. Quoi qu'il en soit, la bave de côté, je penser em> J'ai quelque chose qui fonctionne pour vous Au lieu de faire. P> (defn future-some [futures]
(if (empty? futures)
false
(let [realized (filter realized? futures)]
(if (some deref realized)
true
(recur (remove (set realized) futures))))))
Juste pour contribuer au processus de pensée, la question est venue après avoir lu ceci: Tomasp.net/blog /fsharp-variations-joinads.aspx . Ils ont dû créer une extension spéciale du compilateur pour l'activer, mais à la fin, cela permet non seulement de la correspondance de modèle ci-dessus, mais non seulement sur les bits ASYNC. Je pense que le clojure est le type de langage qui pourrait se prêter à une solution extrêmement élégante au problème.
@DAXFOHL Merci pour le lien. Peut-être qu'un jour, si / quand je sais quoi que ce soit à propos de F # et / ou de monads, je peux apprécier davantage à ce sujet.
En supposant que vous ne souhaitez pas interroger les contrats à terme tous les x millis et que vous ne pouvez pas contrôler la création des contrats à terme / threads ou le FN qu'ils exécutissent, la solution est juste pour créer encore plus de threads, chaque fil en attente Pour un avenir:
(defn wait-for-any [& futures] (let [how-many-left (atom (count futures)) p (promise) wait-and-notify (fn [f] (fn [] (if @f (deliver p true) (when (zero? (swap! how-many-left dec)) (deliver p false)))))] (dorun (map (comp future-call wait-and-notify) futures)) @p)) (defn sleep-and-return [what-to-return sleep-time] (future (Thread/sleep sleep-time) what-to-return)) (time (println (wait-for-any (sleep-and-return false 1000) (sleep-and-return false 2000) (sleep-and-return false 3000) (sleep-and-return false 4000) (sleep-and-return false 5000)))) >>>false >>>"Elapsed time: 5000.933906 msecs" (time (println (wait-for-any (sleep-and-return false 1000) (sleep-and-return true 2900) (sleep-and-return true 3000) (sleep-and-return false 4000) (sleep-and-return false 5000)))) >>>true >>>"Elapsed time: 2901.309695 msecs"
Ceci est maintenant possible avec test avec (constamment faux) et (constamment vrai): p> core.async code>, comme décrit dans ma réponse à la nouvelle avec des processus de running de running et comparant leurs retours question. Cette réponse définit
thread-and code>; Cette question appelle à
thread-ou code>:
;; prints :foo before returning true
(thread-or #(do (Thread/sleep 3000) true)
#(do (Thread/sleep 1000) (println :foo)))
;; does not print :foo
(thread-or #(do (Thread/sleep 3000) true)
#(do (Thread/sleep 7000) (println :foo)))
Toute chance que cela fonctionne avec Core.Match, de sorte que le prédicat du premier ensemble de résultats correspondant soit ensuite exécuté?
Vous pouvez certainement utiliser Core.Match avec des valeurs renvoyées des canaux, ce ne sont que des valeurs de clojure régulières après tout. Dans un Thread-ou Code> Variante Court-circuit court-circuit de la première valeur de Truthy, vous pouvez simplement renvoyer cette valeur, puis utiliser core.match dessus. Si vous souhaitez faire un
thread-and code>, puis à l'aide de fin d'utilisation.Match sur la première valeur à calculer, vous devez stocker la première valeur renvoyée dans une boucle local (ajoutez-le comme la seconde boucle locale -
res1 code>, disons - avec la valeur initiale
nil code>, puis
(RECUR ... (NILL? ) Résultat res1)) code>, avec
... code> comme avant).
Bien sûr, vous devrez le retourner à partir de thread-et code> dans le cas de la véracité. (Sauf si vous voulez câbler votre correspondance dans
thread-et code>; ou vous pouvez le réécrire afin que vous puissiez transmettre cette logique de l'extérieur en tant que fonction.)
En fait, donnez-moi une minute et je posterai thread-ou code>; J'allais réellement le faire à l'origine mais avons fini par coller dans
fil-et code> pour une raison quelconque.
OK, voici thread-ou code>. Également disponible dans ce Gist .
Incidemment, par écrit les commentaires ci-dessus, j'étais initialement convaincu que c'était à propos de la question autre i>; Ensuite, j'ai remarqué que j'avais collé thread-et code> ici aussi. Désolé pour la confusion.
Et voici un GIST avec un thread-ou code> (en prenant un Nombre arbitraire de fonctions à appeler) sur la base des promesses.
Dax, faire des valeurs "retour" futures? Non, parce que les futurs ne sont pas des fonctions. Les contrats à terme (aka différés ou promesses) sont résolus i> avec des valeurs conceptuellement très différentes des fonctions qui renvoient une valeur. Tenez votre esprit autour de la différence et votre problème devrait devenir beaucoup plus clair.
@ Beetroot-Beetroot Oui, je comprends cela. Toutefois, étant donné le manque de réponses sur cette question, je me demande si la réponse est vraiment si claire. Avez-vous quelque chose en tête? J'ai quelques idées, mais la plupart sont assez compliqués et j'espérais une réponse simple à ce qui semble un problème simple. J'ai mis à jour la question avec un libellé plus précis.
Dax, alors que je comprends les contrats à terme en termes généraux, je ne connais pas cette langue particulière. Je pense que la réponse de @ Alextaggart est proche de ce que vous voulez, mais vous devez obtenir les deux promesses (probablement par des appels de fonction) plutôt que de les générer à l'intérieur
foo code>.
Si vous pouvez lire JavaScript, je peux vous montrer en principe comment faire cela. Vous auriez besoin de traduire dans Crojure.