特征序列
我们知道Observable可以创建可观察序列。那么还有其他类型的Obserable吗?
- single
- 产生一个元素或者一个error事件
- 不会共享变化
- SingleEvent有两种.success(element) .error(error)
我们看到这个序列很像我们网络请求中的回调要么成功,要么失败。
官网给的一个例子
func getRepo(_ repo: String) -> Single<[String: Any]> {
return Single<[String: Any]>.create { single in
let task = URLSession.shared.dataTask(with: URL(string: "https://api.github.com/repos/\(repo)")!) { data, _, error in
if let error = error {
single(.error(error))
return
}
guard let data = data,
let json = try? JSONSerialization.jsonObject(with: data, options: .mutableLeaves),
let result = json as? [String: Any] else {
single(.error(DataError.cantParseJSON))
return
}
single(.success(result))
}
task.resume()
return Disposables.create { task.cancel() }
}
}
如何订阅
getRepo("ReactiveX/RxSwift")
.subscribe { event in
switch event {
case .success(let json):
print("JSON: ", json)
case .error(let error):
print("Error: ", error)
}
}
.disposed(by: disposeBag)
或者使用下面的方式
getRepo("ReactiveX/RxSwift")
.subscribe(onSuccess: { json in
print("JSON: ", json)
},
onError: { error in
print("Error: ", error)
})
.disposed(by: disposeBag)
- Completable
- 只能产生一个completed事件或者error事件
- 它不会发出任何元素
- 不会共享状态
- CompletableEvent 包括 .completed .error
如果我们只是关心一个任务是否完成了或者失败了,而不需返回某些元素,那么我们就可以使用这种类型。
官网给的例子
func cacheLocally() -> Completable {
return Completable.create { completable in
// Store some data locally
...
...
guard success else {
completable(.error(CacheError.failedCaching))
return Disposables.create {}
}
completable(.completed)
return Disposables.create {}
}
}
如何订阅
cacheLocally()
.subscribe(onCompleted: {
print("Completed with no error")
},
onError: { error in
print("Completed with an error: \(error.localizedDescription)")
})
.disposed(by: disposeBag)
- Maybe
- 发出一个元素,或者完成,或者失败
- 不会共享状态变化
- MaybeEvent .success(element) .completed .error(error)
如果我们对一件事,如果它成功了就返回某些数据,如果完成了就做一些清理工作,如果失败了就告诉外界错误。
官网的例子
func generateString() -> Maybe<String> {
return Maybe<String>.create { maybe in
maybe(.success("RxSwift")) //如果生成成功
// OR
maybe(.completed) //如果完成了
// OR
maybe(.error(error)) //如果失败了
return Disposables.create {}
}
}
订阅
generateString()
.subscribe(onSuccess: { element in
print("Completed with element \(element)")
},
onError: { error in
print("Completed with an error \(error.localizedDescription)")
},
onCompleted: {
print("Completed with no element")
})
.disposed(by: disposeBag)
- Driver
相对于其它几个序列,这个其他几个不同,它是为我们提供了驱动UI的序列。
- 不会产生error事件
- 状态共享
- 在主线程监听
官网例子
let results = query.rx.text
.throttle(0.3, scheduler: MainScheduler.instance)
.flatMapLatest { query in
fetchAutoCompleteItems(query)
}
results
.map { "\($0.count)" }
.bind(to: resultCount.rx.text)
.disposed(by: disposeBag)
results
.bind(to: resultsTableView.rx.items(cellIdentifier: "Cell")) { (_, result, cell) in
cell.textLabel?.text = "\(result)"
}
.disposed(by: disposeBag)
这段代码做了一下几件事情
- 取得用户稳定输入后的内容
- 发送忘了请求,获取查询结果
- 将结果绑定到tableview上和label上
这里存在两个问题
1、 fetchAutoCompleteItems如果出现错误,将导致整个序列无法工作。当用户输入新的关键字时,将不能发送网络请求。
2、 fetchAutoCompleteItems不在主线程,那么刷新页面也在后台线程,这样就会造成crash
3、返回的结果被绑定到了两个ui上那么每次输入完后就会进行两次网络请求
我们可以使用下面的代码进行优化
let results = query.rx.text
.throttle(0.3, scheduler: MainScheduler.instance)
.flatMapLatest { query in
fetchAutoCompleteItems(query)
.observeOn(MainScheduler.instance) //在主线程监听
.catchErrorJustReturn([]) // 出现错误默认值
}
.shareReplay(1) //结果共享
results
.map { "\($0.count)" }
.bind(to: resultCount.rx.text)
.disposed(by: disposeBag)
results
.bind(to: resultsTableView.rx.items(cellIdentifier: "Cell")) { (_, result, cell) in
cell.textLabel?.text = "\(result)"
}
.disposed(by: disposeBag)
使用driver进行优化
let results = query.rx.text.asDriver() //转换成driver序列
.throttle(0.3, scheduler: MainScheduler.instance)
.flatMapLatest { query in
fetchAutoCompleteItems(query)
.asDriver(onErrorJustReturn: []) //转换成driver序列,给出默认值
}
results
.map { "\($0.count)" }
.drive(resultCount.rx.text) //使用driver进行绑定
.disposed(by: disposeBag)
results
.drive(resultsTableView.rx.items(cellIdentifier: "Cell")) { (_, result, cell) in
cell.textLabel?.text = "\(result)"
}
.disposed(by: disposeBag)
ControlEvent的几个特征
- 不会产生error事件
- 在主线程监听
- 在主线程订阅
- 共享状态变化
网友评论