Я хотел бы использовать memoize
для функции, которая использует core.async
и <!
, например
(defn foo [x]
(go
(<! (timeout 2000))
(* 2 x)))
(В реальной жизни это может быть полезно для кеширования результатов обращений к серверу)
Я смог добиться этого, написав версию memoize для core.async (почти такой же код, как у memoize):
(defn memoize-async [f]
(let [mem (atom {})]
(fn [& args]
(go
(if-let [e (find @mem args)]
(val e)
(let [ret (<! (apply f args))]; this line differs from memoize [ret (apply f args)]
(swap! mem assoc args ret)
ret))))))
Пример использования:
(def foo-memo (memoize-async foo))
(go (println (<! (foo-memo 3)))); delay because of (<! (timeout 2000))
(go (println (<! (foo-memo 3)))); subsequent calls are memoized => no delay
Мне интересно, есть ли более простые способы добиться того же результата.
**Примечание: мне нужно решение, которое работает с <!
. Для <!!
см. этот вопрос: Как запомнить функцию который использует core.async и блокирует чтение канала? **