promesa icon indicating copy to clipboard operation
promesa copied to clipboard

Sequential computation macro

Open chr15m opened this issue 2 years ago • 3 comments

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

chr15m avatar Dec 17 '23 08:12 chr15m

That is interesting, but after looking a referenced gist, I see a very different set of operations and each one has its own use cases and its own impl. Is not the same if you want collect the results (aka reduce-like) or just need to execute N number of tasks secuentially without collecting the result. Can we elaborate a bit the real needed use case?

niwinz avatar May 12 '25 13:05 niwinz

I've had both use-cases before, both collecting the results and also executing without collecting the results. Thanks for your consideration!

chr15m avatar May 26 '25 08:05 chr15m

I guess if there is a way to run a set of promises sequentially (each waiting for previous resolve) and collecting up the results, then the other use-cases are possible from that:

  • Keep all results.
  • Discard all results.
  • Keep only the final result.

chr15m avatar May 26 '25 08:05 chr15m