clojure - 似乎不需要>!!或 <!!在 Clojurescript 中?

标签 clojure clojurescript

我一定在这里遗漏了一些非常明显的东西,但我正在尝试设置一个非常基本的程序,将一个项目放到一个 channel 上,然后阻止,直到我可以再次取下它。整个程序如下:

(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 

我之前有过那个错误,当我忘记 :refer chan in (如果我只是打开 channel ,然后再次关闭它,程序运行良好)

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

最佳答案

clojurescript 中的可用内容与 core.async 的 clojure 版本存在一些差异。

由于 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)))
    

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

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

    你可以想到go宏生成一个新线程,该线程最终将开始并发执行,并立即将控制权返回到下一条代码指令。

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

    关于clojure - 似乎不需要>!!或 &lt;!!在 Clojurescript 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21400464/

    相关文章:

    clojure - 你如何接受黑色文件上传

    compilation - CLJS : Hardcode the compilation date at compilation time

    clojurescript - lein figwheel vs lein cljsbuild auto

    clojure - 修改参数作为多方法的一部分

    windows - 安装 Leiningen 2.6.0(zip 文件)

    vim - 在 Vim 中导航顶级 Lisp/Clojure 表单

    clojure - 如何在 clojure 中转置嵌套向量

    clojure - 引用困惑

    api - ClojureScript API 文档

    clojure - 如何使用 ClojureScript 和 Figwheel 与后端通信?