Clojure(脚本):用于同步推理异步操作的宏

上下文

我正在玩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调用立即返回.

有没有办法通过monads或宏来实现这项工作?那么[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(脚本):用于同步推理异步操作的宏 - 代码日志