|
4 | 4 | (:require [reagent.core :refer [flush]]
|
5 | 5 | [re-frame.handlers :refer [handle]]
|
6 | 6 | [re-frame.utils :refer [warn error]]
|
7 |
| - [cljs.core.async :refer [chan put! <! timeout]])) |
| 7 | + [cljs.core.async :refer [chan put! <! timeout close!]] |
| 8 | + [goog.async.nextTick])) |
8 | 9 |
|
9 | 10 | ;; -- The Event Conveyor Belt --------------------------------------------------------------------
|
10 | 11 | ;;
|
|
25 | 26 | ;; In a perpetual loop, read events from "event-chan", and call the right handler.
|
26 | 27 | ;;
|
27 | 28 | ;; Because handlers occupy the CPU, before each event is handled, hand
|
28 |
| -;; back control to the browser, via a (<! (timeout 0)) call. |
| 29 | +;; back control to the browser, via a (<! (yield)) call. |
29 | 30 | ;;
|
30 | 31 | ;; In some cases, we need to pause for an entire animationFrame, to ensure that
|
31 | 32 | ;; the DOM is fully flushed, before then calling a handler known to hog the CPU
|
|
34 | 35 | ;; (dispatch ^:flush-dom [:event-id other params])
|
35 | 36 | ;;
|
36 | 37 |
|
| 38 | +(defn yield |
| 39 | + "Yields control to the browser. Faster than (timeout 0). |
| 40 | + See http://dev.clojure.org/jira/browse/ASYNC-137" |
| 41 | + [] |
| 42 | + (let [ch (chan)] |
| 43 | + (goog.async.nextTick #(close! ch)) |
| 44 | + ch)) |
| 45 | + |
| 46 | + |
37 | 47 | (defn router-loop
|
38 | 48 | []
|
39 | 49 | (go-loop []
|
40 | 50 | (let [event-v (<! event-chan) ;; wait for an event
|
41 | 51 | _ (if (:flush-dom (meta event-v)) ;; check the event for metadata
|
42 | 52 | (do (flush) (<! (timeout 20))) ;; wait just over one annimation frame (16ms), to rensure all pending GUI work is flushed to the DOM.
|
43 |
| - (<! (timeout 0)))] ;; just in case we are handling one dispatch after an other, give the browser back control to do its stuff |
| 53 | + (<! (yield)))] ;; just in case we are handling one dispatch after an other, give the browser back control to do its stuff |
44 | 54 | (try
|
45 | 55 | (handle event-v)
|
46 | 56 |
|
|
0 commit comments