我正在玩ClojureScript,因此Ajax对我的工作方式如下:
(make-ajax-call url data handler);
其中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]?我相信:
因为我可以用同步步骤而不是异步事件来思考,所以我更清楚了解
我怀疑我不是第一个遇到这个问题的人,所以如果这是一个众所周知的问题,那么“Google for Problem Foo”形式的答案完全有效。
谢谢!
答案 0 :(得分:2)
自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
答案 1 :(得分:1)
宏会改变代码的外观,同时使Ajax调用异步。 这是一个简单的模板宏。另一种方法是在等待结果的函数中包含对make-ajax-call的调用。虽然这些中的任何一个都可以起作用,但它们看起来有点尴尬和“不像ajax”。这些好处值得额外的抽象层吗?
答案 2 :(得分:1)
使用线程宏怎么样?还不够好吗?
(->> update-sidebar! (make-ajax-call "/fetch-new-data" {}))
答案 3 :(得分:1)
我们在async branch跷跷板中对此有了粗略的想法。特别参见seesaw.async命名空间。