Разумно ли использовать каналы 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))))
Другие вопросы по тегам