如何在Clojure中连锁承诺

如何在Clojure中连锁承诺,clojure,Clojure,在Scala中,您可以使用map和flatMap对未来的成功结果运行函数 val x: Future[Int] = ... val y: Future[String] = x.map(_.toString) 是否有比以下更好的Clojure类似物: (def x (promise)) (def y (future (str @x))) 当线程等待x传递时,上面的代码不会阻止它吗?除非您尝试删除y的值,即 (def x (promise)) ;wont block (def y (future

在Scala中,您可以使用
map
flatMap
对未来的成功结果运行函数

val x: Future[Int] = ...
val y: Future[String] = x.map(_.toString)
是否有比以下更好的Clojure类似物:

(def x (promise))
(def y (future (str @x)))

当线程等待
x
传递时,上面的代码不会阻止它吗?

除非您尝试删除y的值,即

(def x (promise)) ;wont block
(def y (future (str @x)))  ;wont block
(print @y) ;will block
就类比而言,代码看起来不错。但如果您想要某种更具声明性的链接期货的方式,即概念上的缩减,那么您可以使用
reduce
,如下所示:

(def x (promise))
(def final (reduce #(future (%2 @%1)) 
                   x 
                   [inc dec (partial + 10) str]))

(deliver x 10)
@final => "20"

你甚至可以提出一个类似于线程的宏,但是为每个线程表达式创建未来,但是我认为如果你可以使用普通函数来实现这一点,那就太过分了。

而执行
(def y(future(str@x))
的线程不会阻塞,它不会在后台生成一个线程来执行
(str@x)
部分吗?这难道不会阻止吗?这是我应该关心的事情吗(即,池是否有严格的界限)?@Huw据我所知,你不能像Scala那样将回调附加到期货上。该线程来自无限线程池。所以你应该只在你创造了大量的未来的时候才考虑。