Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- (defn- add-argument-last
- [form arg]
- `(~@form ~arg))
- (defn- callback [sc fc]
- `(fn [err# res#]
- (cljs.core.async.macros/go
- (when err#
- (~'>! ~fc err#))
- (if (nil? res#) ;; Sometimes the result is nil
- (cljs.core.async/close! ~sc)
- (~'>! ~sc res#)))))
- (defn- success-value-or-throw
- "Attempt to get the successful callback value and add it to the success channel (SC),
- or throw an exception and add it to the failure channel (FC)."
- [sc fc]
- `(let [[v# c#] (~'alts! [~sc ~fc])]
- (try
- (if (= c# ~sc)
- v#
- (let [err (js/Error. v#)]
- (cljs.core.async/put! ~fc err)
- err))
- (finally
- (cljs.core.async/close! ~sc)
- (cljs.core.async/close! ~fc)))))
- (defn- transform
- "Transform FORMS to replace ... at the end of a form with a channel callback handler."
- [forms]
- (if (list? forms)
- (if (= (last forms) '...)
- (let [sc (gensym) fc (gensym)] ; sc -> success, fc -> fail
- `(let [~sc (cljs.core.async/chan)
- ~fc (cljs.core.async/chan)]
- (do
- ~(add-argument-last (map transform (butlast forms))
- (callback sc fc))
- ~(success-value-or-throw sc fc))))
- (map transform forms))
- forms))
- (defmacro asynchronize
- "Asynchronize a standard JS callback. It will return an async channel or
- throw an exception on failure."
- [& forms]
- `(cljs.core.async.macros/go
- ~@(map transform forms)))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement