2013-12-12 16 views
8

Ich bin neu in Clojure und schreibe eine Bibliothek, die Post-Ergebnisse für eine Antwort an einen Server sendet. Ich nehme die Antwort auf, indem ich sie auf einen asynchronen Core-Kanal lege. Ist das gesund oder gibt es einen besseren Weg?Ist es sinnvoll, core.async-Kanäle zu verwenden, um die Post-Ergebnisse von http-kit in clojure zu konsumieren?

ist hier ein hohes Maß Überblick darüber, was ich tue:

(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)))))) 

Hier ist der eigentliche Code, den ich verwende: https://github.com/gilmaso/btc-trading/blob/master/src/btc_trading/btc_china.clj#L63

Es funktioniert, aber ich habe eine harte Zeit hatte die Überprüfung, ob Das ist der richtige Weg.

Antwort

8

core.async ist leistungsfähig, aber es scheint wirklich, wenn es darum geht, komplexere Asynchronität zu koordinieren. Wenn Sie immer auf die Antwort blockieren wollen, würde ich empfehlen, ein promise anstatt verwenden, da es ein wenig einfacher ist:

(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))) 

Wenn Sie nicht möchten, mit Kanälen arbeiten, kann der Code ein wenig gereinigt werden. Wichtig ist, dass Sie nicht alles in einen go Block verpacken müssen; go ist erstaunlich für die Koordinierung asynchronicity, aber letztlich ist ein Kanal ein Kanal:

(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)))) 
+0

Vielen Dank für die durchdachte Antwort! Ich entschied mich, mit Versprechen/Lieferung zu gehen. Ich hatte diese seltsame Idee, dass es meinen Hauptthread blockieren würde, aber ich lag falsch damit. Gedrückt! – gilmaso