RxSwift 变换操作(Transforming Observ

2018-09-25  本文已影响33人  darrenW

变换操作指的是对原始的Observable序列进行一些转换,类似于 Swift 中CollectionType的各种转换

1. buffer

buffer操作符将缓存Observable中发出的新元素,当元素达到某个数量,或者经过了特定的时间,它就会将这个元素集合发送出来。

buffer.png
🌰:
let disposeBag = DisposeBag()
let subject = PublishSubject<String>()

subject.buffer(timeSpan: 1, count: 3, scheduler: MainScheduler.instance)
        .subscribe{ print($0) }
        .disposed(by: disposeBag)
subject.onNext("A")
subject.onNext("B")
subject.onNext("C")

subject.onNext("🐯")
subject.onNext("🐭")
subject.onNext("🐱")

运行结果如下:

next(["A", "B", "C"])
next(["🐯", "🐭", "🐱"])

有一点疑问,对于bufferRxSwift的解释是

Projects each element of an observable sequence into a buffer that's sent out when either it's full or a given amount of time has elapsed, using the specified scheduler to run timers

RxSwift中,它的意思是当缓冲区满了或超过了给定的时间时,就会发出缓冲区。可是如果我们把上述代码稍微改变一下

let disposeBag = DisposeBag()
let subject = PublishSubject<String>()

subject.buffer(timeSpan: 1, count: 3, scheduler: MainScheduler.instance)
        .subscribe{ print($0) }
        .disposed(by: disposeBag)
subject.onNext("A")
subject.onNext("B")
subject.onNext("C")

//  subject.onNext("🐯")
subject.onNext("🐭")
subject.onNext("🐱")

运行结果如下:

next(["A", "B", "C"])

并没有后面的内容。因为我在很多文章里都看到说如果规定时间内不够要求的数量也会发出(有几个发几个,一个都没有发空数组 [])。所以,这点值得注意。

2. window

let disposeBag = DisposeBag()
let subject = PublishSubject<String>()

subject.window(timeSpan: 1, count: 3, scheduler: MainScheduler.instance)
    .subscribe{ print($0) }
    .disposed(by: disposeBag)

subject.onNext("A")
subject.onNext("B")
subject.onNext("C")

subject.onNext("🐯")
subject.onNext("🐭")
subject.onNext("🐱")

运行结果如下:

next(RxSwift.AddRef<Swift.String>)
next(RxSwift.AddRef<Swift.String>)
next(RxSwift.AddRef<Swift.String>)
next(RxSwift.AddRef<Swift.String>)
......

可见他在不断打印next(RxSwift.AddRef<Swift.String>)
如果把代码改成这样:

let disposeBag = DisposeBag()
let subject = PublishSubject<String>()

subject.window(timeSpan: 1, count: 3, scheduler: MainScheduler.instance)
    .subscribe(onNext: {
        print("subscribe:\($0)")
        $0.asObservable()
            .subscribe{ print($0) }
            .disposed(by: disposeBag)
    })
    .disposed(by: disposeBag)

subject.onNext("A")
subject.onNext("B")
subject.onNext("C")

subject.onNext("🐯")
subject.onNext("🐭")
subject.onNext("🐱")

运行结果如下:

subscribe:RxSwift.AddRef<Swift.String>
next(A)
next(B)
next(C)
completed
subscribe:RxSwift.AddRef<Swift.String>
next(🐯)
next(🐭)
next(🐱)
completed
subscribe:RxSwift.AddRef<Swift.String>
completed
subscribe:RxSwift.AddRef<Swift.String>
completed

3.map

map操作符将Observable的每个元素应用你提供的转换方法,然后返回含有转换结果的Observable

map.png
let disposeBag = DisposeBag()
Observable.of(1,2,3)
    .map{ $0 * 2 }
    .subscribe(onNext: { print($0) })
    .disposed(by: disposeBag)

运行结果如下:

2
4
6

其实,swift中也有一个高级函数map,可以对数组中的每一个元素做一次处理

let array = [1, 2, 3]
let nums = array.map {
    return $0 * 2
}
print(nums)

结果得出:

[2, 4, 6]

4. flatMap

flatMap.png
let disposeBag = DisposeBag()
let first = BehaviorSubject.init(value: "A")
let second = BehaviorSubject.init(value: "B")
let variable = Variable.init(first)

variable.asObservable()
    .flatMap{ $0 }
    .subscribe(onNext: { print($0) })
    .disposed(by: disposeBag)
first.onNext("1")
variable.value = second
second.onNext("2")
first.onNext("3")

打印结果如下:

A
1
B
2
3

我们依然可以在Swift中找到高级函数flatMap,它相比map有两点不同

只举一个🌰:

let array = [[1, 2, 3], [4, 5, 6]]
let nums = array.flatMap{ $0 }
print(nums)

运行结果如下:

[1, 2, 3, 4, 5, 6]

5. flatMapLatest

flatMapLatestflatMap的唯一区别是:flatMapLatest只会接收最新的value事件

flatMapLatest.png
将上述代码中flatMap改为flatMapLatest
let disposeBag = DisposeBag()
let first = BehaviorSubject.init(value: "A")
let second = BehaviorSubject.init(value: "B")
let variable = Variable.init(first)

variable.asObservable()
    .flatMapLatest{ $0 }
    .subscribe(onNext: { print($0) })
    .disposed(by: disposeBag)
first.onNext("1")
variable.value = second
second.onNext("2")
first.onNext("3")

运行结果如下:

A
1
B
2

6. concatMap

concatMap操作符将源Observable的每一个元素应用一个转换方法,将他们转换成Observables。然后让这些Observables 按顺序的发出元素,当前一个Observable元素发送完毕后,后一个Observable才可以开始发出元素。等待前一个Observable产生完成事件后,才对后一个Observable进行订阅

concatMap.png
let disposeBag = DisposeBag()
let first = BehaviorSubject.init(value: "A")
let second = BehaviorSubject.init(value: "B")
let variable = Variable.init(first)

variable.asObservable()
    .concatMap{ $0 }
    .subscribe(onNext: { print($0) })
    .disposed(by: disposeBag)
first.onNext("1")
first.onNext("2")

variable.value = second
second.onNext("3")
second.onNext("4")

first.onCompleted()
second.onNext("5")

运行结果如下:

A
1
2
4
5

7. scan

scan操作符将对第一个元素应用一个函数,将结果作为第一个元素发出。然后,将结果作为参数填入到第二个元素的应用函数中,创建第二个元素。以此类推,直到遍历完全部的元素。

scan.png
let disposeBag = DisposeBag()
Observable.of(1, 2, 3, 4, 5)
    .scan(0) { acum, elem  in
        acum + elem
    }
    .subscribe(onNext: { print($0) })
    .disposed(by: disposeBag)

运行结果如下:

1
3
6
10
15

8. groupBy

let disposeBag = DisposeBag()
Observable<Int>.of(0, 1, 2, 3, 4, 5)
    .groupBy { (element) -> String in
        return element % 2 == 0 ? "偶数" : "奇数"
}
    .subscribe { (event) in
        switch event {
        case .next(let group):
            group.asObservable().subscribe({ (event) in
                print("key:\(group.key)  event:\(event)")
            })
            .disposed(by: disposeBag)
        default:
            print("")
        }
}.disposed(by: disposeBag)

运行结果如下:

key:偶数  event:next(0)
key:奇数  event:next(1)
key:偶数  event:next(2)
key:奇数  event:next(3)
key:偶数  event:next(4)
key:奇数  event:next(5)
key:奇数  event:completed
key:偶数  event:completed
上一篇 下一篇

猜你喜欢

热点阅读