Sam*_*uel 14 clojure clojurescript
我必须在这里遗漏一些非常明显的东西,但我正在尝试设置一个非常基本的程序,将一个项目放到一个通道上,然后阻止,直到我再次取消它.整个计划如下:
(ns shopping-2.core
(:require [cljs.core.async :as async :refer [>!! <!! put! chan <! close! <!!]]))
(let [c (chan)]
(>!! c "hello")
(.write js/document (<!! c))
(close! c))
Run Code Online (Sandbox Code Playgroud)
我得到的JavaScript错误是:
Uncaught TypeError: Cannot call method 'call' of undefined
Run Code Online (Sandbox Code Playgroud)
在我忘记之前我有这个错误:引用chan(如果我只是打开通道,然后再关闭它,程序运行正常)
但是,当我想使用<!!或>!!宏时,这段代码似乎会窒息.
Joa*_*uin 34
clojurecript中的core.async的clojurescript中可用的内容存在一些差异.
因为JVM上的clojure具有真正的线程,所以它使用真实线程和go块提供并发模式:
真实线程使用宏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)))
Run Code Online (Sandbox Code Playgroud)
无论如何,这个例子有一个并发问题,因为<! >!函数是阻塞的,并且你在同一个例程中放入一个chan ,例程将阻塞(>! c "hello")指令并且它永远不会读取,肯定会使你的程序挨饿.
你可以使用put!fn 来解决这个问题,它可以不受阻塞地放置,或者在不同的例程中有效地运行这些指令,我认为这样可以更好地证明你的意图.
(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")))
Run Code Online (Sandbox Code Playgroud)
在并发线程版本中,您将看到即使首先运行的代码也是读取,它实际上是另一个例程,因此稍后运行的代码(>!)有效地运行解锁第一个例程.
您可以将go宏视为生成一个最终将同时开始执行的新线程,并将控制权立即返回到下一个代码指令之后.
我建议阅读代码漫游,忽略特定部分(>!! <!!等)和一些非常好的swannodette教程(如Clojurescript 101和Communicating Sequential Processes)