funcool / promesa

A promise library & concurrency toolkit for Clojure and ClojureScript.
https://funcool.github.io/promesa/latest/
Mozilla Public License 2.0
498 stars 58 forks source link

Sequential computation macro #148

Open chr15m opened 11 months ago

chr15m commented 11 months ago

It would be great if there was a way to run a series of promises sequentially, waiting for the previous one to finish, and return a vec of all promises for use with p/all. This is different to creating a map of promise returning functions as that would run in parallel not sequentially. See discussion on Slack here.

Here is an implementation using reduce:

(p/let [result
          (p/all
            (reduce
              (fn [col panel-choice]
                (conj col
                      (p/let [_ (last col)]
                        (something-returning-promise panel-choice))))
              []
              panel-choices))]
    (print "reduce" result))

Here is an implementation using p/loop and p/recur:

(p/let [result
          (p/loop [choices panel-choices results []]
            (if (empty? choices)
              results
              (p/let [result (something-returning-promise
                               (first choices))]
                (p/recur (rest choices)
                         (conj results result)))))]
    (print "loop/recur" result))

You can test this in nbb with promises.cljs here: https://gist.github.com/chr15m/c5f943b6aa2c6089c04f04897b3cef81