【问题标题】:RxSwift How to subscribe a observable only one time?RxSwift 如何只订阅一次 observable?
【发布时间】:2023-03-15 09:03:01
【问题描述】:

我想订阅一个 observable,但在某些逻辑上,我会重新订阅它。如果我不想为它写一些特殊的逻辑,我如何在添加新订阅时处理最后一个订阅?或者,当我订阅它时,我怎么知道这个 observable 是否已经被订阅了?

【问题讨论】:

    标签: swift rx-swift


    【解决方案1】:

    您正在寻找的最简单的解决方案确实是他们为此提供的方法 - func take(_ count: Int)。

    这是一个游乐场示例:

    import RxSwift
    
    var variable = Variable(1)
    variable.asObservable().take(1).subscribe(
        onNext: { print("onNext: \($0)") },
        onError: { print("onError: \($0)") },
        onCompleted: { print("onCompleted") },
        onDisposed: { print("onDisposed") })
    variable.value = 2
    
    print("done")
    

    结果是:

    onNext: 1
    onCompleted
    onDisposed
    done
    

    是的,这在您想通过流过滤事件的地方非常有用,在存储订阅不方便的地方。

    【讨论】:

      【解决方案2】:

      你为什么要这样做?您具体想解决什么问题?

      处置订阅的常用方法是使用处置包。

      func subscribeMyObservable()
      {
          disposeBag = DisposeBag()
      
          myObservable
             .subscribe(onNext: { print("Whatever") }
             .addDisposableTo(disposeBag)
      }
      

      请注意我在每次订阅前如何重新创建一次性用品?这将摆脱以前的订阅。

      【讨论】:

      • 谢谢你的回答。有一些逻辑我需要订阅动态盟友,所以有时可能会重新订阅一个 observable,所以我只是认为可能有一些特殊的 observable,如果有新的订阅,它将自动取消上一个。或其他一些聪明的方式,现在,我的解决方案有点像你的。
      • 您可以查看takeWhile 或takeUntil 运算符,但我认为最好的方法就是我所描述的。
      【解决方案3】:

      .switchLatest() 运算符是你的朋友

      let eventObservableWrapper = PublishSubject<Observable<MyEvent>>()
      let eventObservable = eventObservableWrapper.switchLatest() // use this one for subscriptions
      
      // to switch to another observable, call -
      eventObservableWrapper.onNext(someNewEventObservable)
      

      在此处查看有关 switch 工作原理的更多信息 - http://reactivex.io/RxJava/javadoc/rx/Observable.html#switchOnNext(rx.Observable)

      【讨论】:

        【解决方案4】:

        如果我没记错的话,你想做的是订阅而不是在项目发出后取消订阅。

        如果这是你想要的,你可以使用relay,你永远不会取消订阅。

          /**
             * ReplayRelay it works just like hot observables, once that an observer subscribe, the Relay will replay all items already emitted
             * to another observer.
             * it should return 1,2,3,4,5 for both observers.
             */
            @Test
            public void testReplayRelay() {
                ReplayRelay<String> relay = ReplayRelay.create();
                relay.subscribe(result -> System.out.println("Observer1:" + result));
                relay.call("1");
                relay.call("2");
                relay.call("3");
                relay.subscribe(result -> System.out.println("Observer2:" + result));
                relay.call("4");
                relay.call("5");
            }
        

        您可以在这里查看更多示例https://github.com/politrons/reactive/blob/master/src/test/java/rx/relay/Relay.java

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-02-02
          • 1970-01-01
          • 1970-01-01
          • 2020-08-16
          • 2019-05-10
          • 1970-01-01
          相关资源
          最近更新 更多