Чтобы смоделировать ошибку, мы можем «смоделировать» своего рода обратный вызов:
(let [callback (atom nil)
on-data (fn [fun]
(reset! callback fun))
chan (async/chan)]
Если мы попытаемся добавить обратный вызов с помощью (on-data #(async/go (async/put! chan %)))
, это будет превышать предел.Кроме того, поскольку мы используем async/go
, это приведет к тому, что сообщения внутри канала будут не в порядке.
Единственный способ, который я обнаружил, чтобы исправить это, - создать бесконечный список * 1008.* внутри atom
и каждый обратный вызов выберет первый элемент, опубликует сообщение и удалит первый для списка.Тогда у нас может быть doseq
внутри блока go
, который будет публиковать для нас сообщения:
(let [inf-list (atom (map (fn [_] (async/promise-chan)) (range)))]
; We need to iterate over inf-list before anything
(let [lst @inf-list]
(async/go
(doseq [c lst]
(async/>! chan (async/<! c)))))
(on-data #(do
(async/put! (first @inf-list) %)
(swap! inf-list rest))))