可观察的RxSwift目的

时间:2020-11-08 00:03:18

标签: swift rx-swift

我正在学习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。任何帮助表示赞赏。

2 个答案:

答案 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.textpasswordTextField.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,您必须传递一个块才能获得相同的结果。这只是一个例子。有很多用例。

相关问题