是否可以将此 ClojureScript 转换为 JavaScript?

Is it possible to convert this ClojureScript to JavaScript?

我的朋友向我展示了一个使用 ClojureScript 宏的博客 post,他声称所提供的代码无法优雅地转换为 JavaScript,因为 JavaScript 缺少语言中的宏支持。具体来说,此代码段中的 go 宏在 JavaScript

中是不可能的
(def c (chan))

(defn render [q]
  (apply str
    (for [p (reverse q)]
      (str "<div class='proc-" p "'>Process " p "</div>"))))

(go (while true (<! (timeout 250)) (>! c 1)))
(go (while true (<! (timeout 1000)) (>! c 2)))
(go (while true (<! (timeout 1500)) (>! c 3)))

(defn peekn
  "Returns vector of (up to) n items from the end of vector v"
  [v n]
  (if (> (count v) n)
    (subvec v (- (count v) n))
    v))

(let [el  (by-id "ex0")
      out (by-id "ex0-out")]
  (go (loop [q []]
        (set-html! out (render q))
        (recur (-> (conj q (<! c)) (peekn 10))))))

来源:http://swannodette.github.io/2013/07/12/communicating-sequential-processes/

我有点犹豫是否相信如果没有某种宏库就无法以一种优雅的方式完成。我不是在寻找一种以不同方式执行相同行为的解决方案(例如 setTimeout 的三个无限循环等),而是与原始 "spirit" 相同的解决方案。

来自the same blog, only six weeks later

Last night I expressed some frustration about the state and future of concurrency in JavaScript. I ended up having a little bit of back and forth with David Herman and he pointed out that ES6 Generators can express Go and core.async's flavor of CSP. […]

What follows is a minimal amount of code that works in Node.js 0.11 with the ES6 harmony command line setting. […] The insight is to combine Generators with Channels.

所以是的,你需要可以 yield 的 ES6 生成器和一个 CSP 库(不是内置在 JS 中),但是你将拥有 完全相同的精神作为原来的。

如果 ES7 获得 async/await 语法,您还可以使用基于承诺的通道实现,并且能够使用立即调用的 asyncchronous 函数表达式 (IIAFE) 而不是 go 调用。也看看over here.