这可能是处理环中异步通道的最佳方式,基本上我需要在我的处理程序中获取我的通道的响应然后提供响应
(GET "/slow/:a" [a] (slow-request2 a))
;;this function do a slow operation simulating a slow request
(defn slow-response [a]
(let [ch (!/chan 1)]
(!/go (Thread/sleep 10000)
(print "running slow")
(!/>! ch (+ 1 a)))
ch))
;;based in the recommendation from http://www.reddit.com/r/Clojure/comments/2ka3na/how_do_you_organize_your_coreasync_code/cljbz2q
(defn slow-request [a]
(!/go-loop
[v (!/<! (slow-response a))]
(when v (do
(print "response v")
{:status 200 :body v}))))
(defn slow-request2 [a]
(!/go
(while true
{:status 200 :body (!/<! (slow-response a))})))
不幸的是我收到了这个错误
java /lang.IllegalArgumentException at / slow / 10没有实现方法:: render of protocol:#'compojure.response / Renderable for class:clojure.core.async.impl.channels.ManyToManyChannel
似乎比处理程序尝试响应整个go块而不是我的请求体,我找不到解决方案来处理响应而没有副作用,除了使用阻塞响应
这可能是这种情况下最好的方法吗?
注意:我正在使用vertx / ring适配器,因此http / kit现在不是一个选项,我需要找到一种方法来响应响铃中的句柄通道
答案 0 :(得分:1)
您需要对core.async通道进行阻止,以强制它为某个值。否则,处理程序将返回通道本身而不是通道上的值。
如果您的请求需要支持异步,请考虑使用Pedestal
此外,在内部去块时更喜欢超时chan到线程/睡眠。