Skip to content

Instantly share code, notes, and snippets.

@beders
Last active January 26, 2022 22:18

Revisions

  1. beders revised this gist Oct 25, 2019. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion mini-promise.cljc
    Original file line number Diff line number Diff line change
    @@ -26,7 +26,7 @@
    Start with a promise object and then chain as usual.
    Returns a promise object.
    (promise-> (js/Promise.resolved 1) inc inc js/console.log)
    (promise-> (js/Promise.resolve 1) inc inc js/console.log)
    => #object[Promise [object Promise]]
    (prints 3 on console)
  2. beders revised this gist Sep 13, 2018. 1 changed file with 13 additions and 7 deletions.
    20 changes: 13 additions & 7 deletions mini-promise.cljc
    Original file line number Diff line number Diff line change
    @@ -1,19 +1,24 @@

    (defn create-function-call [param expr]
    "Create an sexp for calling expr with a first argument provided by a promise.
    If expr is a list (already in form suitable for a function call), insert the first argument at second position,
    otherwise turn expr into a function call expression.
    otherwise turn expr into a function call expression, unless the function is an fn, which is simply returned.
    println -> (fn [param] (println param))
    (* 2) -> (fn [param] (* param 2))
    (fn [result]) -> (fn [result])
    "
    (list 'fn [param]
    (if (list? expr)
    (conj (conj (rest expr) param) (first expr))
    (list expr param)
    )
    )
    (if (and (list? expr) (= 'fn (first expr))) ;; expr can be used per se
    expr
    (list 'fn [param]
    (if (list? expr)
    (conj (conj (rest expr) param) (first expr))
    (list expr param)
    )
    ))
    )

    (defmacro promise-> [promise & body]
    @@ -37,3 +42,4 @@
    ~@(map (fn [expr] (list '.then (create-function-call param expr))) body-then)
    ~@(map (fn [expr] (list `.catch (create-function-call param expr))) body-catch)
    )))

  3. beders created this gist Sep 6, 2018.
    39 changes: 39 additions & 0 deletions mini-promise.cljc
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,39 @@
    (defn create-function-call [param expr]
    "Create an sexp for calling expr with a first argument provided by a promise.
    If expr is a list (already in form suitable for a function call), insert the first argument at second position,
    otherwise turn expr into a function call expression.
    println -> (fn [param] (println param))
    (* 2) -> (fn [param] (* param 2))
    "
    (list 'fn [param]
    (if (list? expr)
    (conj (conj (rest expr) param) (first expr))
    (list expr param)
    )
    )
    )

    (defmacro promise-> [promise & body]
    "Chain promises with an optional :catch clause. Works with any promise implementation.
    Start with a promise object and then chain as usual.
    Returns a promise object.
    (promise-> (js/Promise.resolved 1) inc inc js/console.log)
    => #object[Promise [object Promise]]
    (prints 3 on console)
    Optionally add one ore more :catch error-handler sexp to register a (.catch ...) function:
    (promise-> (js/Promise.reject \"error\") inc inc :catch js/console.error)
    => #object[Promise [object Promise]]
    (prints \"error\" on console)
    "
    (let [[body-then [_ & body-catch]] (split-with #(not= :catch %) body)
    param (gensym 'result)
    ]
    `(-> ~promise
    ~@(map (fn [expr] (list '.then (create-function-call param expr))) body-then)
    ~@(map (fn [expr] (list `.catch (create-function-call param expr))) body-catch)
    )))