我正在尝试制作一个显示食谱的Clojurescript应用程序。
相关代码如下(也可用as a gist):
(defn load-recipes [data]
(go (if (not (:loaded? @data))
(let [recipes-data (<! (fetch-recipes data))]
(om/update! data :recipes recipes-data)
(om/update! data :loaded? true))
(println "Data already loaded"))))
(defn define-routes [data]
(defroute home-path "/" []
(om/update! data :view :home))
(defroute "/random" []
(go (loop [loaded? (:loaded? (om/value data))]
(if-not loaded? (do (println "Waiting for data...")
(recur (:loaded? (om/value data))))
(do (om/update! data :tag
(rand-nth
(vec (apply set/union (map :tags (:recipes @data))))))
(om/update! data :view :random)))))))
(defn app-view [data owner]
(reify
om/IWillMount
(will-mount [_]
(do
(load-recipes data)
(define-routes data)))
om/IDidMount
(did-mount [_]
#_(fetch-recipes data))
om/IRender
(render [_]
(html data))))
我想要完成的事情:
我现在得到的是浏览器中的无限循环。发生了什么事?
另一种选择是在go块中包装首先需要数据获取的所有路由,并将(<! (load-recipes))
放在第一行。
PS:我最终得到了
(defn ensure-recipes-loaded [data]
(go (if (not (:loaded? (om/value data)))
(do (om/update! data :view :loading)
(let [recipes-data (<! (fetch-recipes data))]
(om/update! data :recipes recipes-data)
(om/update! data :loaded? true)))
(println "Data already loaded"))))
(defn define-routes [data]
(defroute home-path "/" []
(om/update! data :view :home))
(defroute "/random" []
(go
(<! (ensure-recipes-loaded data))
(do (om/update! data :tag
(rand-nth
(vec (apply set/union (map :tags (:recipes @data))))))
(om/update! data :view :random))))
(defroute "/random/:tagname" [tagname]
(go (<! (ensure-recipes-loaded data))
(om/update! data :tag tagname)
(om/update! data :view :random)))
(defroute "/recipe/:link" [link]
(go (<! (ensure-recipes-loaded data))
(om/update! data :view :recipe)
(om/update! data :permalink link)))
(defroute "*" [*]
(go (<! (ensure-recipes-loaded data))
(om/update! data :view :default))))
答案 0 :(得分:2)
使用loop
构造,其中没有任何(停放)通道操作等待,这完全违背了core.async的精神。请记住,JavaScript是单线程的,因此如果您不执行执行线程,则无法运行其他任何内容。
在加载操作完成后,关闭一个通道。需要阻止时尝试从该通道读取;如果它返回nil
,它已完成,如果它阻止,那么你有所需的等待操作。如果您想在等待期间定期做某事,那么请从该频道和超时中读取。