2014-02-18 14 views
24

Jeder spricht darüber, wie großartig core.async ist und wie es die Ereignisbehandlung in Clojurescript verbessert. Ich habe das Tutorial ClojureScript 101 verfolgt und sehe keinen klaren Vorteil aus diesen Codebeispielen. Was vermisse ich?Was ist der Vorteil von core.async in Clojurescript?

Warum ist die Verwendung von core.async hier besser?

(defn listen [el type] 
    (let [out (chan)] 
    (events/listen el type 
     (fn [e] (put! out e))) 
    out)) 

(defn dosomethingasync 
    [e] 
    (js/console.log "async: " e)) 

(let [clicks (listen (dom/getElement "search1") "click")] 
    (go (while true (dosomethingasync (<! clicks))))) 

gegen

(defn dosomethingcallback 
    [e] 
    (js/console.log "callback: " e)) 

(events/listen (dom/getElement "search2") "click" dosomethingcallback) 
+1

Andere gute Ressource! http://www.infoq.com/interviews/baldridge-core-async – tangrammer

Antwort

34

Gute Frage!

Ich denke, der erste Schritt, um den Vorteil zu verstehen Timothy Baldridge Video

Und unter meinem Versuch wäre:

Ich denke, dass die Unterschiede nach oben wird klar, wenn wir ein wenig Code ändern.

Erstens versuchen, den Satz zu markieren „Es kommt eine Zeit, in allen guten Programmen, wenn Komponenten oder Subsysteme stoppen müssen direkt miteinander kommunizieren“ auf der clojure blog geschrieben extrahiert aus der Präsentation von core.async. Ich denke, dass wir die Eingabeereignisse Kanal von der let fn trennen kann:

(def clicks (listen (dom/getElement "search1") "click")) 

(go 
    (while true 
    (dosomethingasync (<! clicks)))) 

(put! clicks "this channel can be written from differents parts of your code") 

Zweitens mit core.async können wir asynchrone Aufrufe schreiben, wie wir synchrone Anrufe schreiben werden (sequentieller Code). Ein Beispiel für diese Situation erfordert mehr als einen Kanal:

(def clicks (listen (dom/getElement "search1") "click")) 

(def keys-pressed (listen (dom/getElement "search1") "keypress")) 

(def to-out (chan)) 

(go 
    (while true 
    (let [click-recieved (<! clicks)] 
     (dosomethingasync click-recieved) 
     (>! to-out "click recieved!") 
     (let [other-input-waited (<! keys-pressed)] 
     (dosomethingwithkey other-input-waited) 
     (>! to-out "keypressed recieved!") 
     ) 
    ) 
    )) 

Und schließlich denke ich, dass Sie nicht richtig die Bedeutung der Callback-Funktion. Wenn wir von einer Callback-Funktion sprechen, denke ich, dass wir uns auf eine Funktion beziehen, die neben ihren eigenen Parametern eine Funktion "Callback" erhält. Am Ende der Ausführung der Funktion rufen wir die Callback-Funktion auf, um den Ausführungsablauf an den ursprünglichen Punkt zurückzugeben. Ändern Sie Ihre Funktion kommen wie folgt „Rückruf“:

(defn dosomethingcallback 
    [e call-back-fn] 
    (js/console.log "callback: " e) 
    (call-back-fn)) 

Und wenn wir versuchen, etwas Ähnliches wie die gleiche Verhalten mit früheren Code core.async Beispiel erreicht Ausgabe:

(defn do-key 
    [call-back-fn e] 
    (.log js/console "before callback key") 
    (call-back-fn e)) 

(defn do-click 
    [call-back-fn e] 
    (.log js/console "before callback click") 
    (call-back-fn e)) 

(defn key-callback-fn [e] 
    (.log js/console (str "doing some work with this key: " e)) 
) 

(defn click-callback-fn [e] 
    (.log js/console (str "doing some work with this click" e)) 
    (events/listen (dom/getElement "search2") "keypress" (partial do-key key-callback-fn))) 


    (events/listen (dom/getElement "search2") "click" (partial do-click click-callback-fn))