上下文
我正在使用 ClojureScript,因此 Ajax 对我来说工作如下:
(make-ajax-call url data handler);
处理程序看起来像这样:
(fn [response] .... )
现在,这意味着当我想说“获取新数据,并更新左侧边栏”之类的内容时,我的最终结果如下:
(make-ajax-call "/fetch-new-data" {} update-sidebar!) [1]
现在,我更愿意将其写为:
(update-sidebar! (make-ajax-call "/fetch-new-data" {})) [2]
但是它不会工作,因为 make-ajax 调用会立即返回。
问题
是否有通过 monad 或宏来实现此功能的方法?这样 [2] 就会自动重写为 [1] 吗?我相信:
- 不会有任何性能损失,因为它被重写为 [1[
这对我来说推理起来更清晰,因为我可以用同步步骤而不是异步事件来思考
我怀疑我不是第一个遇到这个问题的人,所以如果这是一个众所周知的问题,“Google for Problem Foo”形式的答案是完全有效的。
谢谢!
最佳答案
自从2013年6月28日,clojure core.async lib发布的时间起,你或多或少都可以这样做: https://gist.github.com/juanantonioruz/7039755
这里粘贴了代码:
(ns fourclojure.stack
(require [clojure.core.async :as async :refer :all]))
(defn update-sidebar! [new-data]
(println "you have updated the sidebar with this data:" new-data))
(defn async-handler [the-channel data-recieved]
(put! the-channel data-recieved)
)
(defn make-ajax-call [url data-to-send]
(let [the-channel (chan)]
(go
(<! (timeout 2000)); wait 2 seconds to response
(async-handler the-channel (str "return value with this url: " url)))
the-channel
)
)
(update-sidebar! (<!! (make-ajax-call "/fetch-new-data" {})))
更多信息:
* http://clojure.com/blog/2013/06/28/clojure-core-async-channels.html
* https://github.com/clojure/core.async/blob/master/examples/walkthrough.clj
关于Clojure(脚本): macros to reason about async operations synchronously,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11171066/