如何在clojure中优雅地停止重复功能?

时间:2014-03-23 16:46:19

标签: clojure

我有一个播放一小段音乐的程序。我想让它在一个循环中播放一段时间,但我希望能够优雅地停止它,也许是用一个按键。

(顺便说一句,我试图避免说"循环"或"按键",因为我不想在这个方向上引导答案。)

我仍然是一个充满斗篷的初学者,而我目前只是在使用REPL。

  • 是时候让我毕业了更好的方式来运行我的音乐功能吗?

  • 如何在需要时告诉我的功能优雅地停止?

2 个答案:

答案 0 :(得分:4)

这实际上取决于你的实际使用情况:你想杀死音乐(即在播放时打断它),还是只是想阻止它下次播放?

后一种情况很容易用一个承诺来处理,一旦你认为沉默应该落下来就可以填补:

(defn play-music! []
  (let [p (promise)]
    (future 
      (while (= (deref p 0 ::timeout) ::timeout)
        ...))
    #(deliver p ::stop)))

这将返回一个可以调用(不带参数)的函数来停止循环,例如:

(let [stop-fn (play-music!)]
  ;; ... do important music stuff ...
  (stop-fn))

这将在代码段停止播放后停止循环。如果你想真正打断它,你可以使用future-cancel(但实际结果取决于你的音乐片段是否真的可以中断):

(defn play-music! []
  (let [fut (future
              (while true
                ...))]
    #(future-cancel fut)))

这也会返回停止功能。有多种方法可以重复执行操作,其中大部分都是详细的,例如: here,包括如何停止产生的循环。

答案 1 :(得分:1)

xsc的答案很复杂,信息量很大,而且可能更好,但值得一提的非常非常简单的答案可能会有效:在Leiningen中运行它,并使用Ctrl-C停止该功能,我觉得相当优雅 - 虽然不是很优雅。