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使用
  1. 创建 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
}
  1. 可以使用如下方式使用这个 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)
    }
}
  1. 也可以使用 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)

posted on 2020-04-11 20:51  码上翻身  阅读(442)  评论(0编辑  收藏  举报

导航