Skip to content

Instantly share code, notes, and snippets.

@daigotanaka
Last active August 29, 2015 14:27
Show Gist options
  • Save daigotanaka/161719e816725434b25c to your computer and use it in GitHub Desktop.
Save daigotanaka/161719e816725434b25c to your computer and use it in GitHub Desktop.
Macro to define subscriber functions in ClojureScript
; the macro source
; To understand pub sub in clojure and ClojureScript, read this:
; https://yobriefca.se/blog/2014/06/04/publish-and-subscribe-with-core-dot-asyncs-pub-and-sub/
; define this in my-app/src/my-app/macros.clj
(ns my-app.macros)
(defmacro defsubfn
"Macro for subscriber function in pub-sub pattern"
[fnname channel body]
`(do
(def ~fnname (cljs.core.async/chan))
(defn ~(symbol (str fnname "-react")) [~channel]
(cljs.core.async.macros/go-loop [] (~@body) (recur)))
(~(-> (str fnname "-react") symbol) ~fnname)))
; cljs example
; define in my-app/src/my-app/core.cljs
(ns my-app.core
(:require
[cljs.core.async :refer [chan <! >! pub sub]]
)
(:require-macros
[cljs.core.async.macros :refer [go go-loop]]
[my-app.macros :refer [defsubfn]]
))
(def publisher (chan))
(def publication (pub publisher #(:topic %)))
; define what you want to do
(defsubfn console-out channel
(let [obj (<! channel)] (.dir js/console (str "Topic " (:topic obj) " got: " (:data obj)))))
; make console-out to react to :my-topic
(sub publication :my-topic console-out)
; now publish in :my-topic. console-out is async-triggered
(def some-data "Hello")
(go (>! publisher {:topic :my-topic :data some-data}))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment