我的朋友向我展示了一篇利用ClojureScript宏的博客文章,他声称由于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的三个无限循环等),而是一个与原始行为具有相同“精神”的解决方案。
答案 0 :(得分:5)
来自the same blog, only six weeks later:
昨晚我对国家和未来表示了一些沮丧 JavaScript中的并发性。我最后得到了一些回报 与David Herman一起,他指出ES6发电机可以 表达Go和core.async的CSP风格。 [...]
以下是在Node.js 0.11中运行的最少量代码 使用ES6和声命令行设置。 [...]洞察力是 将发电机与通道结合起来。
所以,是的,您需要能够yield
的ES6生成器和一个CSP库(不是内置于JS中),但是您将拥有完全相同的精神作为原作。
如果ES7获得async
/ await
语法,您还可以使用基于承诺的渠道实施,并且可以使用立即调用的 async
chronous 函数表达式(IIAFE)而不是go
调用。还要看看over here。