文内介绍的是过滤操作符的一些实际使用场景.
额外介绍一些过滤操作符以及一些实际开发的做法, 包括如下:
-
share 操作符
-
filter 操作符
-
将老的异步代码转换为返回可观察序列
-
takeLast 操作符
-
take(_: scheduler:)即只在固定时间段内取元素, 否则自动取消订阅. -
throttle 操作符: 在固定时间段内只取第一个元素.
代码如下所示:
swift
/* 1. share 操作符 如果不作处理的话, 每次针对某个 Observable 的订阅均会引起 Observable 调用 create. 且可能每次 create 时序列中的 元素都和之前的不一样了. 故可以使用 share 操作符来避免这种多余的 create 发生. share 操作符的原理是: 只有当订阅者的数量从 0 到 1 时才会调用 create. 如果之后的订阅者进来, share 则会提供之前已经创建 好的订阅供它们使用. 当所有的订阅都被释放后, share 也会将共享序列释放掉. 这个操作符暂时没有例子. */ /* 2. filter 操作符: 过滤效果和 swift 本身提供的类似. 另外可以利用 filter 操作符来做一些额外的工作, 比如在判断的同时进行一些计算, 并将结果保存到对象的属性中. */ private func filterElem() { exampleOf(msg: "过滤操作符: filter", action: { bag in let obv = Observable.of(1, 3, 5, 7, 9, 2, 4, 6, 8, 10) obv.filter({ $0 % 2 == 0 }).subscribe(onNext: { print($0) }, onError: { print($0) }, onCompleted: { print("完成") }, onDisposed: { print("被释放") }).disposed(by: bag) }) } /* 3. 将老的异步代码转换为返回 Observable 或 Traits 或 Subject 的办法很简单: */ private func createAnObservable() { let observable = Observable<Data>.create({ observer in let disposeables = Disposables.create() let session = URLSession.shared session.dataTask( with: URL(string: "https://www.baidu.com")!, completionHandler: { data, resp, error in if let error = error { observer.onError(error) } observer.onNext(data!) observer.onCompleted() }).resume() return disposeables }) observable.subscribe(onNext: { print($0) }, onError: { print($0) }, onCompleted: { print("完成") }, onDisposed: { print("被释放") }).disposed(by: disposeBag) } /* 4. takeLast 操作符: 不用再费劲心机想跳过多少多少个了, 直接取最后一个 */ private func takeLastElem() { exampleOf(msg: "takeLast 操作符", action: { bag in let obv = Observable.of(1,2,3,4,5,6) obv.takeLast(1) .subscribe(onNext: { print($0) }, onError: { print($0) }, onCompleted: { print(" takeLast 的那个订阅完成") }, onDisposed: { print("释放 takeLast 订阅") }).disposed(by: bag) }) } /* 5. take(_: scheduler:) 在等待一段时机后自动结束某个订阅: 在网络操作下非常常见. 通过下面这个例子可以发现, 停止订阅时正好间隔了 5 秒(时间在 μs 即微秒级别上有误差.) */ private func takeSomeTime() { let publish = PublishSubject<Void>() print("当前时间戳: \(Date().timeIntervalSinceReferenceDate)") publish.take(5.0, scheduler: MainScheduler.instance).subscribe(onNext: { print("发布了!") print("当前时间戳: \(Date().timeIntervalSinceReferenceDate)") }, onError: { print($0) }, onCompleted: { print("完成") print("当前时间戳: \(Date().timeIntervalSinceReferenceDate)") }, onDisposed: { print("被释放") print("当前时间戳: \(Date().timeIntervalSinceReferenceDate)") }).disposed(by: disposeBag) publish.onNext(()) } /* 6. throttle 操作符: 过滤掉指定时间段内的相邻元素, 即固定时间段内只取一个元素. 这个操作符用来处理连续点击的情况非常有用. 暂无示例. */