Mar*_*ark 9 clojure core.async
请考虑以下代码段:
(let [chs (repeatedly 10 chan)]
(doseq [c chs]
(>!! c "hello"))
(doseq [c chs]
(println (<!! c))))
Run Code Online (Sandbox Code Playgroud)
执行此操作将永远挂起.这是为什么?
如果我这样做(go (>! c "hello")),它的工作正常.
Leo*_*hin 15
要进行异步放置,请使用 clojure.core.async/put!
(let [chs (repeatedly 10 chan)]
(doseq [c chs]
(put! c "hello"))
(doseq [c chs]
(println (<!! c))))
Run Code Online (Sandbox Code Playgroud)
这在这个例子中起作用,<!!因为所有必要的放置都是异步发生的,因此总是会解锁.请注意以下事项:
>!!并<!!阻止主线程.go例程在主线程上运行,但是它们的代码通过宏扩展进行修改,以便执行控制被反转,并且可以根据core.async通道阻塞/缓冲逻辑的规则依次停止/执行它们.该技术通常被称为IOC(控制反转)状态机.core.async甚至不包含>!!/ <!!.如果您编写的代码与ClojureScript兼容,则只需从go-routines中的通道中获取或从传递给它们的高阶函数中调用它们,take!并始终执行in- goroutines或use put!.是(go (>! ch v))相当于(put! ch v)?
是的,但不一样.put!是一个围绕该core.async.impl.protocols/WritePort put!方法的通道实现的API包装器.宏扩展(go (>! ch v))最终在同一方法调用中发生,但将其包含在许多生成的状态机代码中,以便可能停止放置操作并暂停执行go-routine,直到消费者准备好从ch(尝试(macroexpand `(go (>! ch v)))自己).产生一个go-block只进行一次异步推送操作是一种浪费,并且比立即调用更糟糕put!.go产生并返回一个额外的通道,你可以从中获取它的实体.这使您可以等待在您的示例中不打算执行的执行(针对异步操作).
| 归档时间: |
|
| 查看次数: |
1728 次 |
| 最近记录: |