Skip to content

Instantly share code, notes, and snippets.

@bhb
Created November 7, 2017 15:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bhb/1b950293a0ebc02b28bc25a9457eaf52 to your computer and use it in GitHub Desktop.
Save bhb/1b950293a0ebc02b28bc25a9457eaf52 to your computer and use it in GitHub Desktop.
Two alternatives to structuring dependent side effects.
;; Problem:
;; When user clicks button, we must do async-effect-A, then async-effect-B.
;; We can't start B until A completes, because it needs the result of A.
;; We don't currently need to vary this sequence. We currently only need to
;; do [A, then B], not [A, then B] or [A, then C]
;;;;;; Implementation 1: Using a single re-frame effect
;;; in some component
(rf/dispatch [:user-clicked-foo])
;;; events.cljs
(reg-event-fx
:user-clicked-foo
(fn [_ [_ _]]
{:do-A-and-B nil}))
;; effects.cljs
(reg-fx
:do-A-and-B
(fn []
(async-effect-A
(fn [result]
(async-effect-B result)))))
;;;;;; Implementation 2: Using two re-frame effects
;;; in some component
(rf/dispatch [:do-A [:do-B]])
;;; events.cljs
(reg-event-fx
:do-A
(fn [_ [_ dispatchback]]
{:do-A dispatchback}))
(reg-event-db
:write-result
(fn [db [_ result]]
(assoc db :result result)))
(reg-event-fx
:do-B
(fn [{:keys [db]} [_ _]]
{:do-B (:result db)}))
;; effects.cljs
(reg-fx
:do-A
(fn [dispatchback]
(async-effect-A
(fn [result]
(dispatch [:write-result result])
(dispatch dispatchback)))))
(reg-fx
:do-B
(fn [result]
(async-effect-B result)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment