Разумно ли использовать каналы core.async, чтобы использовать результаты постов http-kit в clojure?
Я новичок в 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
Это работает, но мне было трудно убедиться, что это правильный путь.
1 ответ
core.async
является мощным, но он действительно сияет, когда речь идет о координации более сложной асинхронности. Если вы всегда хотите заблокировать ответ, я бы рекомендовал использовать promise
вместо этого, поскольку это немного проще:
(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))))