Skip to content

Instantly share code, notes, and snippets.

@isaksky
Last active September 15, 2020 14:56
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 isaksky/2cc3779b52305e992c6150863454a9af to your computer and use it in GitHub Desktop.
Save isaksky/2cc3779b52305e992c6150863454a9af to your computer and use it in GitHub Desktop.
Register delayed subscription
(ns foo
(:require [re-frame.core :as rf]
[re-frame.db]
[reagent.ratom :as ra :refer [reaction]])
(:import goog.async.Debouncer))
(defn reg-sub-delayed
"Similar to reg-sub, except the computation is debounced.
It can be called like this:
(reg-sub-delayed
:a-b-sub
(fn [q-vec]
[(subs/subscribe [:a-sub])
(subs/subscribe [:b-sub])])
(fn [[a b] [_]]
(comment \"... compute something expensive with a and b\"))
:interval 500)
Results get wrapped in a map, like this:
{:result <result of handler function called with input signals>
:dirty <boolean - is there a pending update?> }"
[query-id input-signals f & {:keys [interval]
:or {interval 20}}]
(let [update-state (fn [args e]
(let [result (f args e)]
(swap! re-frame.db/app-db
assoc-in
[::computation-id->data e]
{:dirty false :result result})))
debounced-update-state (goog.functions/debounce update-state interval)
trigger-f (fn [args e]
(swap! re-frame.db/app-db
assoc-in
[::computation-id->data e :dirty]
true)
(debounced-update-state args e))]
;; Actual subscription
(rf/reg-sub-raw
query-id
(fn [app-db e]
;; Register helper subscription
(rf/reg-sub-raw
[::computation-id->sub query-id]
(fn [app-db _]
(let [read-cursor (ra/cursor app-db [::computation-id->data e])
sigs (input-signals e)
last-args (atom ::nil)]
(ra/make-reaction
(fn []
(let [args (mapv deref sigs)]
;; Stop the cycle. Avoidable?
(when (not= args @last-args)
(reset! last-args args)
(trigger-f args e)))
@read-cursor)))))
;; React to listening to subscription we just created
(ra/make-reaction
(fn []
@(rf/subscribe [[::computation-id->sub query-id] e]))
:on-dispose
(fn []
;; Clear the helper subscription we created.
(rf/clear-sub [::computation-id->sub query-id])))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment