diff --git a/CHANGELOG.md b/CHANGELOG.md index cee94df..6ac2dec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog # +## Version 10.0.571 + +- Revert deprecation of `then'` and `chain'` +- Add **experimental** `promesa.core/wait-all` helper + + ## Version 10.0.570 - Add `promesa.exec.csp/mult*` alternative multiplexer constructor diff --git a/README.md b/README.md index b66702c..d2ea896 100644 --- a/README.md +++ b/README.md @@ -18,13 +18,13 @@ Here you can look a detailed [documentation][1]. deps.edn: ```clojure -funcool/promesa {:mvn/version "10.0.570"} +funcool/promesa {:mvn/version "10.0.571"} ``` Leiningen: ```clojure -[funcool/promesa "10.0.570"] +[funcool/promesa "10.0.571"] ``` ## On the REPL diff --git a/src/promesa/core.cljc b/src/promesa/core.cljc index 790544e..27c4e5d 100644 --- a/src/promesa/core.cljc +++ b/src/promesa/core.cljc @@ -147,8 +147,14 @@ (pt/-bind (pt/-promise p) (comp pt/-promise f) executor))) (defn then' - {:deprecated "9.3" - :no-doc true} + "Chains a function `f` to be executed when the promise `p` is + successfully resolved. Returns a promise that will be resolved with + the return value of calling `f` with value as single argument; `f` + should return a plain value, no automatic unwrapping will be + performed. + + The computation will be executed in the completion thread by + default; you also can provide a custom executor." ([p f] (pt/-map (pt/-promise p) f)) ([p f executor] @@ -214,12 +220,13 @@ "Chain variable number of functions to be executed serially using `then`." ([p f] (then p f)) - ([p f & fs] (reduce #(then %1 %2) p (cons f fs)))) + ([p f & fs] (reduce then p (cons f fs)))) (defn chain' - {:deprecated "9.3" :no-doc true} + "Chain variable number of functions to be executed serially using + `map`." ([p f] (then' p f)) - ([p f & fs] (reduce pt/-map (pt/-promise p) (cons f fs)))) + ([p f & fs] (reduce #(map %2 %1) (pt/-promise p) (cons f fs)))) (defn handle "Chains a function `f` to be executed when the promise `p` is completed @@ -361,6 +368,23 @@ (c/->> (CompletableFuture/allOf (into-array CompletableFuture promises)) (map (fn [_] (c/mapv pt/-extract promises))))))) + +(defn wait-all + "Given a variable number of promises, returns a promise which resolves + to `nil` when all provided promises complete (rejected or resolved). + + **EXPERIMENTAL**" + [& promises] + (c/let [state (atom (into #{} promises)) + d (deferred)] + (c/run! (fn [p] + (fnly (fn [_ _] + (when-not (seq (swap! state disj p)) + (pt/-resolve! d nil))) + p)) + promises) + d)) + (defn race [promises] #?(:cljs (.race impl/*default-promise* (into-array (c/map pt/-promise promises))) diff --git a/src/promesa/exec/csp.clj b/src/promesa/exec/csp.clj index 2fa0c1e..a766660 100644 --- a/src/promesa/exec/csp.clj +++ b/src/promesa/exec/csp.clj @@ -382,6 +382,7 @@ (pt/-untap! mx ch))))))) (recur)) (pt/-close! mx))) + mx))) (defn mult diff --git a/test/promesa/tests/core_test.cljc b/test/promesa/tests/core_test.cljc index 9a5dcf6..0a4291a 100644 --- a/test/promesa/tests/core_test.cljc +++ b/test/promesa/tests/core_test.cljc @@ -90,14 +90,14 @@ (t/deftest promise-from-nil-value #?(:cljs (t/async done - (p/then (p/promise nil) - (fn [v] - (t/is (= v nil)) - (done)))) + (p/then' (p/promise nil) + (fn [v] + (t/is (= v nil)) + (done)))) :clj - @(p/then (p/promise nil) - (fn [v] - (t/is (= v nil)))))) + @(p/then' (p/promise nil) + (fn [v] + (t/is (= v nil)))))) (t/deftest promise-from-factory @@ -442,6 +442,19 @@ p2 (p/chain p1 inc inc inc)] (t/is (= @p2 5))))) +(t/deftest chaining-using-chain' + #?(:cljs + (t/async done + (let [p1 (promise-ok 100 2) + p2 (p/chain' p1 inc inc inc)] + (p/then p2 (fn [v] + (t/is (= v 5)) + (done))))) + :clj + (let [p1 (promise-ok 100 2) + p2 (p/chain' p1 inc inc inc)] + (t/is (= @p2 5))))) + (t/deftest promisify #?(:cljs (t/async done