Rx Swift 共享 附加作用
共享 附加作用
共享 附加作用:
- Driver
- Signal
- ControlEvent
- ...
不共享 附加作用:
- Single
- Completable
- Maybe
- ...
什么是共享 附加作用,什么是不共享 附加作用?
- 共享 附加作用:
...
let observable: Observable<Teacher> = API.teacher(teacherId: 1)
let shareSideEffects: Driver<Teacher> = observable.asDriver(onErrorDriveWith: .empty())
let observer0: (Teacher) -> () = ...
let observer1: (Teacher) -> () = ...
shareSideEffects.drive(onNext: observer0)
shareSideEffects.drive(onNext: observer1) // 第二次订阅
如果一个序列共享 附加作用,那在第二次订阅时,不会重新发起网络请求,而是共享第一次网络请求(附加作用)。
- 不共享 附加作用:
...
let observable: Observable<Teacher> = API.teacher(teacherId: 1)
let notShareSideEffects: Single<Teacher> = observable.asSingle()
let observer0: (Teacher) -> () = ...
let observer1: (Teacher) -> () = ...
notShareSideEffects.subscribe(onSuccess: observer0)
notShareSideEffects.subscribe(onSuccess: observer1) // 第二次订阅
如果一个序列不共享 附加作用,那在第二次订阅时,会重新发起网络请求,而不是共享第一次网络请求(附加作用)。
因此我们需要注意,如果一个网络请求序列,他不共享 附加作用,那每一次订阅时就会单独发起网络请求。这时最好改用 共享 附加作用 的序列,或者使用 share 操作符。
Single
特殊的Observable:不像 Observable 可以发出多个元素,它要么只能发出一个元素,要么产生一个 error 事件。
- 发出一个元素,或一个 error 事件
- 不会共享附加作用
一个比较常见的例子就是执行 HTTP 请求,然后返回一个应答或错误。不过也可以用 Single 来描述任何只有一个元素的序列。
SingleEvent
为方便使用,RxSwift 还为 Single 订阅提供了一个枚举(SingleEvent)
- success:里面包含该 Single 的一个元素值
- error:用于包含错误
public enum SingleEvent<Element> {
case success(Element)
case error(Swift.Error)
}
- Single使用
- 创建 Single 和创建 Observable 非常相似。下面代码我们定义一个用于生成网络请求 Single 的函数:
func getPlaylist(_ channel: String) -> Single<[String: Any]> {
return Single<[String: Any]>.create { single in
let url = "https://yinyue.fm/j/mine/playlist?"
+ "type=n&channel=\(channel)&from=mainsite"
let task = URLSession.shared.dataTask(with: URL(string: url)!) { 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() }
}
}
//与数据相关的错误类型
enum DataError: Error {
case cantParseJSON
}
- 可以使用如下方式使用这个 Single:
class ViewController: UIViewController {
let disposeBag = DisposeBag()
override func viewDidLoad() {
//获取第0个频道的歌曲信息
getPlaylist("0")
.subscribe { event in
switch event {
case .success(let json):
print("JSON结果: ", json)
case .error(let error):
print("发生错误: ", error)
}
}
.disposed(by: disposeBag)
}
}
- 也可以使用 subscribe(onSuccess:onError:) 这种方式:
class ViewController: UIViewController {
let disposeBag = DisposeBag()
override func viewDidLoad() {
//获取第0个频道的歌曲信息
getPlaylist("0")
.subscribe(onSuccess: { json in
print("JSON结果: ", json)
}, onError: { error in
print("发生错误: ", error)
})
.disposed(by: disposeBag)
}
}
asSingle()
我们可以通过调用 Observable 序列的 .asSingle() 方法,将它转换为 Single。
let disposeBag = DisposeBag()
Observable.of("1")
.asSingle()
.subscribe({ print($0) })
.disposed(by: disposeBag)