如何停止ClojureScript/core.async中的go block?

9
有没有一种优雅的方法来停止正在运行的go块?(不引入标志并污染代码与检查/分支)
(ns example
  (:require-macros [cljs.core.async.macros :refer [go]])
  (:require        [cljs.core.async        :refer [<! timeout]]))

(defn some-long-task []
  (go
    (println "entering")

    ; some complex long-running task (e.g. fetching something via network)
    (<! (timeout 1000)) 
    (<! (timeout 1000))
    (<! (timeout 1000))
    (<! (timeout 1000))

    (println "leaving")))

; run the task
(def task (some-long-task))

; later, realize we no longer need the result and want to cancel it 
; (stop! task)

(关闭!任务)可能吗?- 谷歌第一个结果。 - birdspider
3个回答

5
抱歉,目前使用core.async不可能实现这个。创建一个go块后,你会得到一个普通的通道,用于存放该块的结果,但这并不能让你获得实际块本身的句柄。

4

根据Arthur的回答,你不能立即终止一个 go 块,但是由于你的例子涉及多阶段任务(使用子任务),像下面这样的方法可能会起作用:

(defn task-processor
  "Takes an initial state value and number of tasks (fns). Puts tasks
  on a work queue channel and then executes them in a go-loop, with
  each task passed the current state. A task's return value is used as
  input for next task. When all tasks are processed or queue has been
  closed, places current result/state onto a result channel. To allow
  nil values, result is wrapped in a map:

  {:value state :complete? true/false}

  This fn returns a map of {:queue queue-chan :result result-chan}"
  [init & tasks]
  (assert (pos? (count tasks)))
  (let [queue  (chan)
        result (chan)]
    (async/onto-chan queue tasks)
    (go-loop [state init, i 0]
      (if-let [task (<! queue)]
        (recur (task state) (inc i))
        (do (prn "task queue finished/terminated")
            (>! result {:value state :complete? (== i (count tasks))}))))
    {:queue  queue
     :result result}))

(defn dummy-task [x] (prn :task x) (Thread/sleep 1000) (inc x))

;; kick of tasks
(def proc (apply task-processor 0 (repeat 100 dummy-task)))

;; result handler
(go
  (let [res (<! (:result proc))]
    (prn :final-result res)))

;; to stop the queue after current task is complete
;; in this example it might take up to an additional second
;; for the terminated result to be delivered
(close! (:queue proc))

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接