簡體   English   中英

RxJava - 何時使用帶有create方法的Observable

[英]RxJava - When to use Observable with create method

我正在閱讀教程:

http://code.tutsplus.com/tutorials/getting-started-with-reactivex-on-android--cms-24387

特別是RxAndroid,但它和RxJava幾乎相同。 我不確定我完全理解這個概念。

下面我寫了一個方法,然后是一個示例用法。

我的問題是:這是實現我的函數的正確方法,以便我可以異步地在其他線程上運行它們嗎? 實際上,它們只會返回一個運行真實代碼的已創建的Observable,並處理錯誤和所有這些內容。

或者這是錯的,那么我想知道正確的方法。

Observable<String> googleSomething(String text){
    return Observable.create(new Observable(){
        @Override
        public void call(Subscriber<? super String> subscriber) {
             try {
                String data = fetchData(text); // some normal method
                subscriber.onNext(data); // Emit the contents of the URL
                subscriber.onCompleted(); // Nothing more to emit
            } catch(Exception e) {
                subscriber.onError(e); // In case there are network errors
            }
        }
    });
}

googleSomething("hello world").subscribeOn(Schedulers.io()).observeOn(Schedulers.immediate()).subscribe(...)

還使用Schedulers.immediate()來執行當前線程上的訂戶代碼? 它說“創建並返回一個在當前線程上立即執行工作的調度程序。” 在javadoc,但我不確定。

除非您更有經驗並需要自定義運算符或想要橋接基於舊版addListener / removeListener的API,否則不應該以create開頭。 StackOverflow上有幾個問題使用了create並且是麻煩的來源。

我更喜歡fromCallable ,它讓你生成一個單獨的值或拋出異常,因此不需要那些冗長的defer + just來源。

Schedulers.immediate()立即在調用者的線程上執行其任務,該線程是示例中的io()線程,而不是主線程。 目前,不支持將計算移回Java主線程,因為它需要阻止蹦床,並且通常是一個壞主意。

你幾乎不應該使用create() ,尤其不是初學者。 有更簡單的方法來創建observable,而create()很難正確實現。

大多數情況下,您可以使用defer()輕松繞過create() defer() 例如,在這種情況下你會這樣做:

Observable<String> googleSomething(String text) {
  return Observable.defer(new Func0<Observable<String>>() {
    @Override
    public Observable<String> call() {
      try {
        return Observable.just(fetchData(text));
      } catch (IOException e) {
        return Observable.error(e);
      }
    }
  });
}

如果您沒有使用已檢查的異常,那么您甚至可以擺脫try-catch。 RxJava會自動將任何RuntimeException轉發給訂閱者的onError()部分。

您可以通過Observable.create(new OnSubscribe {})方法創建Observable:

  • 查看defer()運算符,它允許您返回例如Observable.just()和Observable.error(),這樣您就不需要直接觸及訂閱者
  • 更喜歡使用SyncOnSubscribe / AsyncOnSubscribe來處理背壓

Schedulers.immediate()將在它已經存在的線程上保持Observable處理 - 所以在你的情況下它將是Schedulers.io線程之一

你的代碼看起來不錯。 如果你不確定是否在另一個線程上運行。 你可以在調用.subscribe()后立即打印一些內容,並查看輸出的順序。

googleSomething("hello world").subscribeOn(Schedulers.io()).observeOn(Schedulers.immediate()).subscribe(...) 
System.out.println("This should be printed first");

嘗試在fetchData()模擬長時間運行的操作, fetchData()立即打印其他內容。 因為.subscribe()是非阻塞的“這應該先打印”實際上是先打印。

或者,您可以使用打印當前線程。

Thread.currentThread().getName()

在您的observable內外使用它,輸出應該不同。

暫無
暫無

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

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