2013-12-12 6 views
8

Sono un neofita del clojure e sto scrivendo una libreria che invia risultati post su un server per una risposta. Consumo la risposta posizionandola su un canale core.async. È sano o esiste un modo migliore?È ragionevole utilizzare i canali core.async per utilizzare i risultati dei post di http-kit in clojure?

Ecco una panoramica di alto livello di quello che sto facendo:

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

Ecco il codice che sto usando: https://github.com/gilmaso/btc-trading/blob/master/src/btc_trading/btc_china.clj#L63

Funziona, ma ho avuto un momento difficile verificare se è il modo giusto per farlo.

risposta

8

core.async è potente, ma brilla davvero quando si tratta di coordinare l'asincronia più complessa. Se hai sempre voglia di bloccare sulla risposta, mi consiglia di utilizzare un promise invece dal momento che è un po 'più semplice:

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

Se si vuole lavorare con i canali, il codice può essere ripulito un po'. È importante sottolineare che non è necessario avvolgere tutto in un blocco go; go è sorprendente per il coordinamento di asincronicità, ma in definitiva, un canale è un canale:

(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

Grazie per la risposta premurosa! Ho deciso di andare con la promessa/consegna. Avevo questa strana idea che avrebbe bloccato il mio thread principale, ma mi sbagliavo. Spinto! – gilmaso

Problemi correlati