9

我是 clojure 的新手,正在编写一个库,将发布结果发送到服务器以获取响应。我通过将响应放在 core.async 通道上来使用它。这是理智还是有更好的方法?

这是我正在做的事情的高级概述:

(defn my-post-request [channel options]
  (client/post http://www.example.com options
          (fn [{:keys [status headers body error]}] ;; asynchronous handle response
              (go (>! channel body)))))

(defn request-caller [options]
  (let [channel (chan)]
    (my-post-request channel options)
    (json/parse-string (<!! (go (<! channel))))))

这是我正在使用的实际代码:https ://github.com/gilmaso/btc-trading/blob/master/src/btc_trading/btc_china.clj#L63

它有效,但我很难验证这是否是解决此问题的正确方法。

4

1 回答 1

10

core.async功能强大,但在协调更复杂的异步性方面确实很出色。如果您总是想阻止响应,我建议您使用 apromise代替,因为它更简单一些:

(defn my-post-request [result options]
  (client/post http://www.example.com options
          (fn [{:keys [status headers body error]}] ;; asynchronous handle response
              (deliver result body))))

(defn request-caller [options]
  (let [result (promise)]
    (my-post-request result options)
    ; blocks, waiting for the promise to be delivered
    (json/parse-string @result)))

如果您确实想使用频道,可以稍微清理一下代码。重要的是,您不需要将所有内容都包装在一个go块中。go协调异步性是惊人的,但最终,一个通道是一个通道:

(defn my-post-request [channel options]
  (client/post http://www.example.com options
          (fn [{:keys [status headers body error]}] ;; asynchronous handle response
              (put! channel body))))

(defn request-caller [options]
  (let [channel (chan)]
    (my-post-request channel options)
    (json/parse-string (<!! channel))))
于 2013-12-12T06:06:22.757 回答