web-dev-qa-db-ja.com

RxJava Single.just()vs Single.fromCallable()?

誰かがこの質問にいくつかの光を当てることができるかどうか、いつ使うべきか

Single.fromcallable(()-> myObject)

の代わりに

Single.Just(myObject)

ドキュメントからSingle.formcallable

 /**
 * Returns a {@link Single} that invokes passed function and emits its result for each new SingleObserver that subscribes.
 * <p>
 * Allows you to defer execution of passed function until SingleObserver subscribes to the {@link Single}.
 * It makes passed function "lazy".
 * Result of the function invocation will be emitted by the {@link Single}.
 * <dl>
 *   <dt><b>Scheduler:</b></dt>
 *   <dd>{@code fromCallable} does not operate by default on a particular {@link Scheduler}.</dd>
 * </dl>
 *
 * @param callable
 *         function which execution should be deferred, it will be invoked when SingleObserver will subscribe to the {@link Single}.
 * @param <T>
 *         the type of the item emitted by the {@link Single}.
 * @return a {@link Single} whose {@link SingleObserver}s' subscriptions trigger an invocation of the given function.
 */

およびSingle.justのドキュメント

 /**
 * Returns a {@code Single} that emits a specified item.
 * <p>
 * <img width="640" height="310" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/Single.just.png" alt="">
 * <p>
 * To convert any object into a {@code Single} that emits that object, pass that object into the
 * {@code just} method.
 * <dl>
 * <dt><b>Scheduler:</b></dt>
 * <dd>{@code just} does not operate by default on a particular {@link Scheduler}.</dd>
 * </dl>
 *
 * @param item
 *            the item to emit
 * @param <T>
 *            the type of that item
 * @return a {@code Single} that emits {@code item}
 * @see <a href="http://reactivex.io/documentation/operators/just.html">ReactiveX operators documentation: Just</a>
 */
13
bastami82

あなたが言及したユースケースでは、実際には大きな違いはありません。

関数呼び出しによってオブジェクトを動的に作成する必要がある場合はどうなりますか?

_fun getTimeObject() {
    val timeInMillis = System.currentTimeMillis()
    return TimeObject(timeInMillis)
}
_

次に、Single.just(getTimeObject())で、_Singleは、新しい_subscriberがあるときに同じLongを出力します。

ただし、Single.fromcallable(()-> getTimeObject())を使用すると、結果のSingleは、新しいサブスクライバーがいるときの現在の時刻をミリ秒単位で示す異なるLongを発行します。

これは、fromCallableが新しいサブスクライバーを持つたびにラムダを実行するためですLazily

14

通常、放出しているものが単なるオブジェクトではなく、実際には重い計算、I/O、または状態のいずれかを含むメソッド呼び出しの結果である場合に違いに気付くでしょう。

Single.just(x)は、現在のスレッドですぐにxを評価します。その後、すべてのサブスクライバーに対してxの結果が残ります。

Single.fromCallable(y)は、サブスクリプション時および各サブスクライバーごとに、yスケジューラーでsubscribeOn呼び出し可能オブジェクトを呼び出します。


したがって、たとえば、I/O操作をバックグラウンドスレッドにオフロードする場合は、次を使用します。

_Single.fromCallable(() -> someIoOperation()).
    subscribeOn(Schedulers.io()).
    observeOn(AndroidSchedulers.mainThread()).
    subscribe(value -> updateUi(value), error -> handleError(error));
_

Single.just()は現在のスレッドで実行されるため、ここでsomeIoOperation()を使用しても機能しません。

21
laalto

次のような関数がある場合は、fromCallable()を使用する必要があります

MyObject myFunction() {
    // some login here
    return new MyObject();
}

次に、この関数から次のようにSingleを作成できます。

Single.fromCallable(() -> myFunction());

Single.just(myObject)ロジックなしでオブジェクトを出力します。

そのため、特定のアイテムを発行するときにfromCallable()を使用する必要はありません。

1
DenZap

ドキュメントでは、2つの時間アセンブル時間Runtimeを区別しました。

アセンブリ時間さまざまな中間演算子を適用することによるデータフローの準備

Runtimeこれは、フローがアイテムをアクティブに放出している状態です

単にSingle.just()は、メインプロセスの完了後ではなく、アセンブリ時間で評価されます

Single.defer()およびSingle.fromcallable()は、RuntimeのSingleオブジェクトを評価します

公式ドキュメントのコード例を確認してください here

0
aya salama