上有什么在从core.async的Clojure的版本clojurescript提供一定的差异。
因为在JVM的Clojure有真正的线程,它可以使双方的并发模式与真正的线程,并与去块:
真实线程使用宏thread
围住core.async魔术 及其并发宏和函数以两个爆炸声结束,如 <!!
,>!!
,alt!!
和alts!!
。
控制线程 (假线程)的反演使用go
宏以包围core.async魔术 并使用该功能,并在最后一个的一声,像<!
,>!
, alt!
和alts!
。
在clojurescript(在JS运行)有没有真正的线程,所以只有IOC(控制反转)线程可用,这意味着你必须使用并行结构的第二个变体。
你的例子是这样的:
(ns shopping-2.core
(:require-macros [cljs.core.async.macros :refer [go]])
(:require [cljs.core.async :as async :refer [put! chan <! >! close!]]))
(go
(let [c (chan)]
(>! c "hello")
(.write js/document (<! c))
(close! c)))
反正就是例子有一个并发问题,因为<! >!
功能是阻止和你投入一个瓒在同一常规,在常规将阻止(>! c "hello")
指令,它永远不会读取,肯定会让你的程序挨饿。
你可以使用put!
FN这使不阻塞,或者在不同的程序我认为这说明了什么更好,你打算做efectively运行这些说明解决这个问题。
(ns shopping-2.core
(:require-macros [cljs.core.async.macros :refer [go]])
(:require [cljs.core.async :as async :refer [put! chan <! >! close!]]))
;; put! version
(go
(let [c (chan)]
(put! c "hello")
(.write js/document (<! c))
(close! c)))
;; Concurrent version
;; 2 *threads* concurrently running. One is the putter and the other is the
;; reader
(let [c (chan)]
(go
(.write js/document (<! c))
(close! c))
(go
(>! c "hello")))
在并发线程版本,你会看到,即使在运行首先是阅读代码,它实际上是另一种例行这样以后运行代码(>!
)有效运行,疏通第一个例程。
您可以将go
宏想象为产生一个新的线程,该线程将最终开始并发执行,并将控制权立即返回到下一代码指令。
我建议您阅读code walk-through忽略Clojure的特定部位(>!! <!!
等)和一些swannodette's tutorials这是伟大的(如Clojurescript 101和通信顺序进程)
谢谢你这么多的详细解释,一个简单的“ Clojure脚本不包含阻塞宏“本来就够了,但这太棒了! 我实际上已经运行了Clojurescript 101教程,并且我正在执行这个演练,这是我被卡住的原因(第30行介绍了阻塞宏,这正是我试图弄清楚的!) – Samuel
不客气。我试图解释清楚,因为我从不久前就开始涉足core.async,开始时很难做好准备。 从clojure和clojurescript版本的差异应该在core.async回购的地方... – Joaquin