关!没有取消订阅的订阅频道

时间:2016-01-17 20:14:04

标签: clojure clojurescript core.async

在未先使用import UIKit import WebKit class ViewController: UIViewController, WKNavigationDelegate { var webView: WKWebView! var loadingView: WKWebView! @IBOutlet var textField: UITextField! override func loadView() { view = webView webView = WKWebView() webView.navigationDelegate = self webView.backgroundColor = UIColor.whiteColor() webView.opaque = true view = loadingView loadingView = WKWebView() loadingView.navigationDelegate = self loadingView.hidden = true loadingView.alpha = 0.5 loadingView.backgroundColor = UIColor.whiteColor() UIApplication.sharedApplication().statusBarStyle = .Default } override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. let url = NSURL(string: "about:blank")! webView.loadRequest(NSURLRequest(URL: url)) webView.allowsBackForwardNavigationGestures = true let loadingURL = NSBundle.mainBundle().URLForResource("LoaderPhone", withExtension:"html")! self.loadingView.loadRequest(NSURLRequest(URL: loadingURL)) // Notification observer for textField self.textField.addTarget(self, action: "textFieldDidUpdate:", forControlEvents: UIControlEvents.EditingChanged) } func textFieldDidUpdate(textField: UITextField) { if (textField.text!.rangeOfCharacterFromSet(NSCharacterSet.whitespaceCharacterSet()) != nil) { guard let text = textField.text, query = text.stringByAddingPercentEncodingWithAllowedCharacters(.URLQueryAllowedCharacterSet()), url = NSURL(string: "https://google.com/#q=\(query)") else { return } loadingView.hidden = true webView.loadRequest(NSURLRequest(URL: url)) } else { // Validate URL NSURL.validateUrl(textField.text, completion: { (success, urlString, error) -> Void in dispatch_async(dispatch_get_main_queue(), { () -> Void in if (success) { self.loadingView.hidden = true let request = NSURLRequest(URL: NSURL(string: urlString!)!) print(urlString!) self.webView.loadRequest(request) } else { self.webView.stopLoading() self.loadingView.hidden = false print("View is hidden") } }) }) } } } 的情况下,在订阅频道上使用close!会产生什么影响? 这会产生隐式unsub + a unsub的效果,还是会有任何不必要的副作用呢?

2 个答案:

答案 0 :(得分:1)

pubsub是根据mult

实施的
  • 发布渠道的每个主题都对应于注册该主题的第一个订阅时创建的多个

  • 每次sub次调用都会导致对与相关主题相对应的广告tap进行内幕调用。

在内部设置Mults以删除最终放入封闭通道的点击(这在mult的文档字符串中记录)。在订阅的上下文中,这意味着如果订阅频道已关闭,则在第一次将该主题的消息发布到发布频道时,它的抽头将被删除,或者换句话说,close!导致隐含的unsub

请注意,unsubclose!都不会导致主题本身(以及相应的mult)从发布的寄存器中删除。如果您希望这种情况发生,可以使用unsub-all

答案 1 :(得分:0)

我无法确定文档的答案,因此我进行了一项小型异步实验,以确定close!没有unsub是否安全。

(ns pubsub.experiment
  (:require [clojure.core.async :as >]))

(def publisher (>/chan))

(def p (>/pub publisher (constantly nil)))

(def answers (>/chan))

(defn consume
  [label count]
  (let [s (>/sub p nil (>/chan))]
    (>/go-loop [i 0]
      (if (> i count)
        (>/close! s)
        (do
          (>/>! answers [label (>/<! s)])
          (recur (inc i)))))))

(defn -main
  [& args]
  (println "running pubsub experiment")
  (consume :a 1)
  (consume :b 2)
  (consume :c 3)
  (consume :d 4)
  (consume :e 5)
  (>/go-loop []
    (println "result: " (>/<! answers))
    (recur))
  (>/<!! (>/onto-chan publisher (range 10)))
  (System/exit 0))

然后运行它(bench.jar是一个包含clojure加上core.async和其他一些库的uberjar)。

$ java -cp ~/bin/bench.jar:. clojure.main -m pubsub.experiment
running pubsub experiment
result:  [:a 0]
result:  [:b 0]
result:  [:c 0]
result:  [:d 0]
result:  [:e 0]
result:  [:a 1]
result:  [:b 1]
result:  [:c 1]
result:  [:d 1]
result:  [:e 1]
result:  [:b 2]
result:  [:c 2]
result:  [:d 2]
result:  [:e 2]
result:  [:c 3]
result:  [:d 3]
result:  [:e 3]
result:  [:d 4]
result:  [:e 4]
result:  [:e 5]
$ 

正如我们所看到的,close!来电不会干扰任何其他订阅频道,每个频道都会看到我们在结束前所期望的所有结果。