Last active
September 15, 2020 14:56
-
-
Save isaksky/2cc3779b52305e992c6150863454a9af to your computer and use it in GitHub Desktop.
Register delayed subscription
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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