Skip to content

Instantly share code, notes, and snippets.

@hcliff
Created September 27, 2012 15:05
Show Gist options
  • Save hcliff/3794500 to your computer and use it in GitHub Desktop.
Save hcliff/3794500 to your computer and use it in GitHub Desktop.
Clojure macro for async callbacks
(ns async.macros
"Macros to avoid callback soup, act as defer/await "
(:use [taoensso.timbre :as timbre :only (trace debug info warn error fatal spy)]))
(defmacro let-async [bindings & body]
(cond
; when there are no more bindings execute the body
(empty? bindings) `(do ~@body)
; a regular (not async let)
; e.g: [:let one "hello world"]
(= (first bindings) :let)
(let [[_ binding-name binding-value & remaining] bindings]
`(let [~binding-name ~binding-value]
(let-async ~remaining ~@body))
)
; an async let
:else
(let [[binding-name binding-value & remaining] bindings]
`(~binding-value (fn [binding-name#]
(let [~binding-name binding-name#]
(let-async ~remaining ~@body))))
)))
(defmacro async [bindings & body]
`(fn ~bindings ~@body)
)
@hcliff
Copy link
Author

hcliff commented Sep 27, 2012

Usage:

(defn ajax [url]
    (async [success-callback]
        (ajax {:success success-callback :url url})))
(let-async [ajax-response (ajax "http://google.com")
                :let formatted-ajax-request (json-load ajax-response)]
                (do-something-with formatted-ajax-request))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment