RXSwift - 使用connectable operator

2020-08-24  本文已影响0人  内蒙小猿


    public func stamp() -> String {
        let date = Date()
        let formatter = DateFormatter()
        formatter.dateFormat = "HH:mm:ss"
        let result = formatter.string(from: date)

        return result
    }

replay : 当有 新的订阅者 加入后,回访指定个数的 最新信号。replay(N)可以指定回放个数 ,也可用 replayAll回放所有的历史事件。

 let  interval = Observable<Int>.interval(DispatchTimeInterval.seconds(1), scheduler: MainScheduler.instance).replay(2)

        _ = interval.subscribe(onNext: { (num) in
            print("1 - " + self.stamp())
            print("     Subscriber1: \(num)")
        })
        
        _ = interval.connect()
        let current = DispatchTime.now()
         print("开始 - " + self.stamp())

        DispatchQueue.global().asyncAfter(deadline: current + 2) {
            _ = interval.subscribe(onNext: { (num) in
                print("2 - " + self.stamp())
                print("     Subscriber2: \(num)")
            })
        }
        
        DispatchQueue.global().asyncAfter(deadline: current + 4) {
            _ = interval.subscribe(onNext: { (num) in
                print("3 - " + self.stamp())
                print("     Subscriber3: \(num)")
            })
        }
        

执行过程

interval
-----------------0-------------1--------------2-------------3-------------4-----------------
     
Subscriber1
-----------------0-------------1--------------2-------------3-------------4-----------------
     
 
Subscriber2
-------------------------------1-------------2--------------3-------------4-----------------
     
 
Subscriber3
------------------------------------------------------------3--------------4-----------------

 
                            .....replay(2)
     
----------------------------(1,0,1)-----------------------(3,3,2,3)-------------------------

\color{#DEB887}{执行结果:}

\color{#DEB887}{开始 - 13:52:06}

\color{#DEB887}{1 - 13:52:07}
\color{#DEB887}{ \qquad Subscriber1: 0}

\color{#DEB887}{1 - 13:52:08}
\color{#DEB887}{ \qquad Subscriber1: 1}
\color{#DEB887}{2 - 13:52:08}
\color{#DEB887}{\qquad Subscriber2: 0 \qquad replay}
\color{#DEB887}{2 - 13:52:08 }
\color{#DEB887}{\qquad Subscriber2: 1 \qquad replay}

\color{#DEB887}{1 - 13:52:09}
\color{#DEB887}{\qquad Subscriber1: 2}
\color{#DEB887}{2 - 13:52:09}
\color{#DEB887}{\qquad Subscriber2: 2}

\color{#DEB887}{1 - 13:52:10}
\color{#DEB887}{\qquad Subscriber1: 3}
\color{#DEB887}{2 - 13:52:10}
\color{#DEB887}{\qquad Subscriber2: 3}
\color{#DEB887}{3 - 13:52:10}
\color{#DEB887}{\qquad Subscriber3: 2 \qquad replay}
\color{#DEB887}{3 - 13:52:10}
\color{#DEB887}{\qquad Subscriber3: 3 \qquad replay}

\color{#DEB887}{1 - 13:52:11}
\color{#DEB887}{\qquad Subscriber1: 4}
\color{#DEB887}{2 - 13:52:11}
\color{#DEB887}{\qquad Subscriber2: 4}
\color{#DEB887}{3 - 13:52:11}
\color{#DEB887}{ \qquad Subscriber3: 4}

note

buffer:为事件回放提供缓冲区。

回顾知识点: 默认情况订阅者是不共享Observalbe的。我很迷茫不知道你在说啥

     let  interval = Observable<Int>.interval(DispatchTimeInterval.seconds(1), scheduler: MainScheduler.instance).buffer(timeSpan:     DispatchTimeInterval.seconds(4), count: 2, scheduler: MainScheduler.instance)

        _ = interval.subscribe(onNext: { (num) in
            print("1 - " + self.stamp())
            print("     Subscriber1: \(num)")
        })
        
        let current = DispatchTime.now()
         print("开始 - " + self.stamp())

        DispatchQueue.global().asyncAfter(deadline: current + 2) {
            _ = interval.subscribe(onNext: { (num) in
                print("2 - " + self.stamp())
                print("     Subscriber2: \(num)")
            })
        }

buffer 用法解析:(timeSpan 和 count 那个条件先满足都会发信号)

执行过程

// count 先满足条件
interval
-----------------0-------------1--------------2-------------3-------------------------------
     
Subscriber1                         发给订阅和,重置timeSpan
----------------------------(0,1)------------------------(2,3)-----------------------------
     
 
Subscriber2
-----------------------------------------------------------(0,1)----------------------------
                      ......buffer(timeSpan: ......)
     
----------------------------(0,1)-----------------------(2,3)(0,1)-------------------------

\color{#DEB887}{1 - 16:34:02}
\color{#DEB887}{\qquad Subscriber1: [0, 1]}

\color{#DEB887}{1 - 16:34:04}
\color{#DEB887}{\qquad Subscriber1: [2, 3]}
\color{#DEB887}{2 - 16:34:04}
\color{#DEB887}{\qquad Subscriber2: [0, 1]}

\color{#DEB887}{1 - 16:34:06}
\color{#DEB887}{\qquad Subscriber1: [4, 5]}
\color{#DEB887}{1 - 16:34:06}
\color{#DEB887}{\qquad Subscriber2: [2, 3]}

note

代码展示的是 count 先满足条件的情况。

window:由 Observable 填充缓冲区;除了用缓冲区的事件值作为数组发送给订阅者之外,我们还可以让某个时间段内的所有事件,组成一个新的 Observable,这个就是 window。参数使用和buffer 一样,不赘述。

我们的事件序列就会每隔4秒打开一个窗口,每个窗口周期最多处理4个事件,然后关闭当前窗口,打开新的窗口。

要注意每一个窗口周期中的事件,是随着interval中的事件实时发送给订阅者的。\color{}{ \small{ \mathbf{而不是“攒”够了一个窗口周期的 事件后,再发送一个Sub-observable。}} }

为了观察每一个Sub-observable生成到完成的过程,我们只好比较笨的在interval的订阅里,又订阅了一次。

注意这里,\color{}{ \small{ \mathbf{不要用flatMap直接对interval进行变换}} },否则,我们订阅到的,就是对interval所有事件变换后的Observable,这样,就观察不到每一个Sub-observable的onCompleted事件了。


        let  interval = Observable<Int>.interval(DispatchTimeInterval.seconds(1), scheduler: MainScheduler.instance).window(timeSpan: DispatchTimeInterval.seconds(4), count: 4, scheduler: MainScheduler.instance)
        
        print("开始 - " + self.stamp())
        
        _ = interval.subscribe(onNext: { (subObservable: Observable<Int>) in
            
            print("============= Window Open ===============")
            
            _ = subObservable.subscribe(onNext: { (value: Int) in
                print("1 - " + self.stamp())
                print("     Subscriber1: \(value)")
            }, onError: nil, onCompleted: {
                print("============ Window Closed ==============")
            }) {
                print("onDisposed")
            }
        })
       

执行过程

interval
-----------------0--1--2---------------3--4--5--6--7--8-----------------------------------
     
            ...... window(timeSpan: .......)
     
--------open----(0,1,2)---close---open---(3,4,5,6)----close---------------------------------

\color{#DEB887}{执行结果:}

\color{#DEB887}{开始 - 17:29:51}

\color{#DEB887}{Window Open}
\color{#DEB887}{1 - 17:29:52}
\color{#DEB887}{\qquad Subscriber1: 0}
\color{#DEB887}{1 - 17:29:53}
\color{#DEB887}{\qquad Subscriber1: 1}
\color{#DEB887}{1 - 17:29:54}
\color{#DEB887}{\qquad Subscriber1: 2}
\color{#DEB887}{Window Closed}
\color{#DEB887}{onDisposed}

\color{#DEB887}{Window Open}
\color{#DEB887}{1 - 17:29:55}
\color{#DEB887}{\qquad Subscriber1: 3}
\color{#DEB887}{1 - 17:29:56}
\color{#DEB887}{\qquad Subscriber1: 4}
\color{#DEB887}{1 - 17:29:57}
\color{#DEB887}{\qquad Subscriber1: 5}
\color{#DEB887}{1 - 17:29:58}
\color{#DEB887}{\qquad Subscriber1: 6}
\color{#DEB887}{Window Closed}
\color{#DEB887}{onDisposed}

note

buffer 和 window 的异同点:

相同点:

不同点:

1、
2、
上一篇 下一篇

猜你喜欢

热点阅读