似乎无法要求&gt; !!或者<! - !在Clojurescript? - >

时间:2014-01-28 08:32:16

标签: 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))

我得到的JavaScript错误是:

Uncaught TypeError: Cannot call method 'call' of undefined 

在我忘记之前我有这个错误:引用chan(如果我只是打开频道,然后再关闭它,程序运行正常)

但是,当我想使用<!!>!!宏时,此代码似乎会窒息。

2 个答案:

答案 0 :(得分:34)

clojurescript中的core.async的clojurecript有什么不同。

因为JVM上的clojure有真正的线程,所以它提供了真实线程和go块的并发模式:

  1. 真实线程使用宏thread来包含core.async魔法 它的并发宏和函数以两个刘海结尾,比如 <!!>!!alt!!alts!!

  2. 控制线程的反转 (假线程)使用go宏来封装core.async魔法 并使用最后一次爆炸的功能,如<!>!alt!alts!

  3. 在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)))
    

    无论如何,该示例存在并发问题,因为<! >!函数正在阻塞,并且您将在同一例程中放入一个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")))
    

    在并发线程版本中,您将看到即使是首先运行的代码也是读取,它实际上是另一个例程,因此稍后运行的代码(>!)有效地运行解锁第一个例程。 / p>

    您可以将go宏视为产生一个最终将同时开始执行的新线程,并将控制权立即返回到下一个代码指令。

    我建议阅读code walk-through忽略特定部分(>!! <!!等)和一些很棒的swannodette's tutorials(如Clojurescript 101和Communicating Sequential Processes)

答案 1 :(得分:3)

core.async的ClojureScript版本不包含<!!>!!

除了实际来源之外,我无法找到此消息来源:https://github.com/clojure/core.async/blob/56ded53243e1ef32aec71715b1bfb2b85fdbdb6e/src/main/clojure/cljs/core/async.cljs