core.async
is powerful, but it really shines when it comes to coordinating more complex asynchronicity. If you always want to block on the response, I'd recommend using a promise
instead since it's a little simpler:
(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)))
If you do want to work with channels, the code can be cleaned up a bit. Importantly, you don't need to wrap everything in a go
block; go
is amazing for coordinating asynchronicity, but ultimately, a channel's a channel:
(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))))