简体   繁体   English

如何使用core.async代替回调?

[英]How to use core.async in place of callbacks?

I'm using core.async on ClojureScript to avoid using node.js callbacks. 我在ClojureScript上使用core.async以避免使用node.js回调。 The problem is that I'm hitting the 1024 pending messages limit. 问题是我达到了1024个待处理邮件的限制。

To avoid it, I would need to send all messages to channels inside the same go block. 为了避免这种情况,我需要将所有消息发送到同一go块内的通道。 But this is not really possible on core.async because an anonymous function nullifies the effect of go , so I can't do this: 但这在core.async上实际上是不可能的,因为匿名函数会使go的作用无效,所以我不能这样做:

(go
  (. socket on "data" #(>! chan %)))

So, is there a way to get around this limitation? 那么,有没有办法解决这个限制?

I am not sure I understand why it has to be in the same go block. 我不确定我是否理解为什么必须将其放在同一块中。 Normally, you would just do: 通常,您只需执行以下操作:

(. socket on "data" #(go (put! chan %)))

and then process the chan in another go block 然后在另一个go块中处理chan

To simulate the error, we can "simulate" a kind of callback: 为了模拟错误,我们可以“模拟”一种回调:

(let [callback (atom nil)
      on-data (fn [fun]
                (reset! callback fun))
      chan (async/chan)]

If we try to add a callback with (on-data #(async/go (async/put! chan %))) , it'll blow the limit. 如果我们尝试添加带有(on-data #(async/go (async/put! chan %)))的回调,它将超过限制。 Also, as we're using async/go , it'll cause the messages inside the channel to be out of order. 另外,由于我们使用的是async/go ,这将导致通道内的消息混乱。

The only way I found out to fix this is to create an infinite list of promise-chan inside an atom and every callback will pick up the first element, publish a message, and remove the first for the list. 我发现解决此问题的唯一方法是在一个atom内创建一个无限的promise-chan列表,每个回调都将拾取第一个元素,发布一条消息,然后删除该列表的第一个元素。 Then, we can have a doseq inside a go block that'll publish messages for us: 然后,我们可以在go块中添加一个doseq为我们发布消息:

(let [inf-list (atom (map (fn [_] (async/promise-chan)) (range)))]
  ; We need to iterate over inf-list before anything
  (let [lst @inf-list]
    (async/go
     (doseq [c lst]
       (async/>! chan (async/<! c)))))

  (on-data #(do
              (async/put! (first @inf-list) %)
              (swap! inf-list rest))))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM