 
   (_check-clean [this]
     (when (== dirtyness maybe-dirty)
-      (let [ar auto-run]
+      (let [ar auto-run
+            len (arr-len watching)]
         (set! auto-run nil)
-        (doseq [w watching :while (== dirtyness maybe-dirty)]
-          (when (and (instance? Reaction w)
-                     (false? (._check-clean w)))
-            (._try-run w this)))
+        (loop [i 0]
+          (when (< i len)
+            (let [w (aget watching i)]
+              (when (and (instance? Reaction w)
+                         (false? (._check-clean w)))
+                (._try-run w this)))
+            (when (== dirtyness maybe-dirty)
+              (recur (inc i)))))
         (set! auto-run ar))
       (when (== dirtyness maybe-dirty)
         (set! dirtyness clean)))


(defn- notify-deref-watcher! [derefable]
  (when-some [obj *ratom-context*]
    (let [captured (.-cljsCaptured obj)]
      (set! (.-cljsCaptured obj)
            (if (nil? captured)
              (let [old (.-watching obj)]
                (if (and (== 1 (count old))
                         (identical? derefable (first old)))
                  ;; Optimize common case of one deref
                  old
                  #{derefable}))
              (conj captured derefable))))))

(def reaction-counter 0)

(defn reaction-key [r]
  (if-some [k (.-reaction-id r)]
    k
    (->> reaction-counter inc

  (-write writer (str "#<" s " "))
  (pr-writer (binding [*ratom-context* nil] (-deref a)) writer opts)
  (-write writer ">"))


;;; Atom

