簡體   English   中英

在 RxJava 中訂閱 Observable 時遇到問題

[英]Trouble with subscribe to Observable in RxJava

我有一個問題,我的程序沒有從subscribe()方法中的Observable獲得結果。

我正在嘗試構建簡單的控制台應用程序,該應用程序向服務器運行請求,然后打印以控制台結果。 正如我所見,一切正常,但我無法在subsribe()中得到結果。 應用程序似乎在結果返回到方法之前完成。

這是我運行 rquest 的代碼:

coffeeShopApi.getCoffeeShops("")
    .subscribeOn(Schedulers.io())
    .subscribe({
         state.onNext(CoffeeShopViewState.CoffeeShopsLoaded(it))
    }, {
         it.printStackTrace()
         state.onNext(CoffeeShopViewState.Error(it.localizedMessage))
    })

執行此代碼后,程序剛剛結束,退出代碼為 0。它還在主線程中從 main function 運行。 這里可能有什么問題?

您的代碼的問題是您訂閱了另一個線程作為當前線程(主線程)。 因此,您的主線程在調用單個項目的訂閱之前完成。

這是帶有堆棧跟蹤的示例代碼:

System.out.println(Thread.currentThread().getName() + ": start...");

Observable<String> stream = Observable.fromIterable(List.of("a", "b", "c"));
stream.subscribeOn(Schedulers.io())
      .subscribe(next -> System.out.println(Thread.currentThread().getName() + ": " + next), 
                 error -> error.printStackTrace());

Thread.sleep(1000L);

System.out.println(Thread.currentThread().getName() + ": stop...");

堆棧跟蹤:

main: start...
RxCachedThreadScheduler-1: a
RxCachedThreadScheduler-1: b
RxCachedThreadScheduler-1: c
main: stop...

表明observable是在main線程中創建的。 訂閱的執行是在不同的線程RxCachedThreadScheduler-1中完成的。

在同一線程上執行的示例:

System.out.println(Thread.currentThread().getName() + ": start...");

Observable<String> stream = Observable.fromIterable(List.of("a", "b", "c"));
stream.subscribe(next -> System.out.println(Thread.currentThread().getName() + ": " + next), 
                 error -> error.printStackTrace());

System.out.println(Thread.currentThread().getName() + ": stop...");

堆棧跟蹤:

main: start...
main: a
main: b
main: c
main: stop...

根據用例,可能需要等待 stream 執行完成,然后才能進一步處理該方法,例如使用相同的線程或FutureObserver 在其他用例中,將昂貴的計算操作外包到不同的線程是一種可行的解決方案。


問題是它是守護線程嗎? 答案是肯定的。 我附上了測試代碼:

String message = String.format("%s-isDaemon?%s: start...", Thread.currentThread().getName(), Thread.currentThread().isDaemon());
System.out.println(message);

Observable<String> stream = Observable.fromIterable(List.of("a", "b", "c"));
stream.subscribeOn(Schedulers.io())
      .subscribe(next -> {
                 final String innerMessage = String.format("%s-isDaemon?%s: %s", Thread.currentThread().getName(), Thread.currentThread().isDaemon(), next);
                 System.out.println(innerMessage);
                 },
                 Throwable::printStackTrace);

Thread.sleep(1000L);

message = String.format("%s-isDaemon?%s: stop...", Thread.currentThread().getName(), Thread.currentThread().isDaemon());
System.out.println(message);

stackrace 的 Output:

main-isDaemon?false: start...
RxCachedThreadScheduler-1-isDaemon?true: a
RxCachedThreadScheduler-1-isDaemon?true: b
RxCachedThreadScheduler-1-isDaemon?true: c
main-isDaemon?false: stop...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM