我正在学习RxSwift,并试图了解Observable和PublishSubject aka Sequence之间的主要区别。
据我了解,Sequences / PublishesSubject充当Observable和Observer。您可以订阅这些,如果值更改,它们将发出通知。可以更改PublishesSubject。
我的问题是,Observables的目的是什么?我只能使用带有just()
或from()
的固定值来创建Observable。但是我不能更改这些值或添加项目,对不对?因此,我的Observable将仅发出我在init中为其分配的值。那么当实际值不可变时,为什么还需要Observable?
让我们考虑一个返回Observable<UIImage>
的函数。无需返回该Observable,然后继续进行预订,我只需返回一个UIImage。为什么我需要一个可观察的?
如果我创建以下Observable:
let observable = Observable.of(1,2,3)
我会有一个静态的Marble图。我的Observable将发出1,2和3。结束了吗?
我只是不明白为什么我应该使用Observable。任何帮助表示赞赏。
答案 0 :(得分:2)
为帮助您理解,请查看Observable.create
。您将看到需要关闭。每当观察者订阅它时,都会执行此关闭。
因此,如果您想使用just
实现create
,则可以执行以下操作:
func just(_ value: Int) -> Observable {
return Observable.create { observer in
observer.onNext(value)
observer.onCompleted()
return Disposables.create()
}
}
当然,这只会在很长时间内发出静态值,但是您可以做其他事情...
let random = Observable<Int>.create { observer in
observer.onNext(Int.random(in: 0..<10))
observer.onCompleted()
return Disposables.create()
}
以上将发出一个随机值,然后完成。您也可以在闭包中发出网络请求,也可以在每次点击按钮时调用onNext
。 RxCocoa已经有很多...所以例如:
let result = loginButton.rx.tap
.withLatestFrom(Observable.combineLatest(usernameTextField.rx.text, passwordTextField.rx.text))
.map { URLRequest.login(credentials: $0) }
.flatMapLatest { URLSession.shared.rx.data(request: $0) }
.subscribe(onNext: { print("data:", $0) }
loginButton.rx.tap
每次按下按钮都会发出下一个事件。usernameTextField.rx.text
和passwordTextField.rx.text
每次用户在其中一个文本字段中输入数据时都会发出下一个事件。URLSession.shared.rx.data(request:)
会发出一个值。所有这些都是(可观察的)形式。答案 1 :(得分:1)
如果您真的不喜欢主题的可变状态,则可以使用普通的Observable。当您要将ViewModel转换为函数而不是类时,这非常方便。
要回答您的特定问题,
Let´s think of a function which returns an Observable<UIImage>. Instead of returning that Observable and then subscribe on next, I can just return an UIImage. Why do I need a Observable?
答案是,想象一下您无法立即返回UIImage
的情况。这可能是由于网络操作或昂贵的绘图操作所花费的时间。因此它必须是异步的。为此,可以使用Observable<UIImage>
代替UIImage
。这样,您可以立即返回Observable<UIImage>
,但是您的订阅者只有在实际完成处理后才能收到UIImage
。
没有Observables,您必须传递一个块才能获得相同的结果。这只是一个例子。有很多用例。