浅いものから深いものへのRxJavaの単一シリアル実行(1)

RxJava3シングルの紹介

この記事のコードはIntellJ環境でテストされており、直接コピーして実行できます。

IntellJは新しいGradleプロジェクトを作成し、依存関係を導入します

実装「io.reactivex.rxjava3:rxjava:3.0.0」

RxJavaでは、Singleは、ネットワーク要求など、イベント値を1回だけ送信するイベントを記述できます。これには、onSuccessとonErrorの2つのサブスクライブ可能なインターフェイスがあり、いずれかのインターフェイスがトリガーされると自動的にサブスクライブを解除します。

//创建Single
Single<String> single = Single.create(emitter -> {
    emitter.onSuccess("ok");
});

//订阅single
single.subscribe(System.out::println);
复制代码

複数のシングルが連続して実行されます

最初に複数のシングルを作成します

public Single<String> task1() {
    return Single.create((SingleOnSubscribe<String>) em -> {
        em.onSuccess("task-1");
    }).doOnSuccess(s -> {
        System.out.println("发射 ->" + s);
    });
}

public Single<String> task2() {
    return Single.create((SingleOnSubscribe<String>) em -> {
        em.onSuccess("task-2");
    }).doOnSuccess(s -> {
        System.out.println("发射 ->" + s);
    });
}
复制代码

複数の単一タスクを宣言する

Single<String> single1 = task1();
Single<String> single2 = task2();
复制代码

通常は直接使用されるワーカースレッド。Schedulers.io()ここでは、スレッドプールを使用してスレッドにログを出力します。

Executor executor = Executors.newSingleThreadExecutor();
复制代码

シナリオ1:シリアルに実行し、各結果を受け取る

Single.concat(single1, single2)
        .subscribeOn(Schedulers.from(executors))
        .subscribe(s -> {
            System.out.println("接收到->" + s);
        });
复制代码

結果:

发射 ->task-1
接收到->task-1
发射 ->task-2
接收到->task-2
复制代码

シナリオ2:前のシングルの結果に従って、後者のシングルを実行するかどうかを決定します

たとえば、ネットワークからの要求がない場合は、最初にデータベースキャッシュからデータを読み取ります

Single.concat(single1, single2)
        .subscribeOn(Schedulers.from(executors))
        .takeUntil(s -> {
            return !"".equals(s);
        })
        .filter(s -> {
            return !"".equals(s);
        })
        .subscribe(s -> {
            System.out.println("接收到->" + s);
        });
复制代码

結果:

发射 ->task-1
接收到->task-1
复制代码

takeUntilここでは、 ANDfilter演算子を使用して、条件付き判断を実装し、不要な要求結果をフィルタリングします。

takeUntil条件がtrueを返す場合、次のシングルは実行されず、結果が直接返されます。takeUntil条件がfalseを返す場合、出力された値filterはオペレーターでフィルターで除外され、次のシングルの実行が続行されます。

デフォルトの戻り値と例外処理を提供する

複数のシングルの実行結果がフィルタリングされている場合、サブスクライバーは値を受け取りません。この時点でデフォルトの戻り値を指定できます。

結果が空の場合は、演算子を使用single()してデフォルトの戻り値を指定します

onErrorReturn()演算子による例外の処理

Single.concat(single1, single2)
        .subscribeOn(Schedulers.from(executors))
        .takeUntil(s -> {
            return false;//此处测试全都执行
        })
        .filter(s -> {
            return true;//此处测试全都不满足过滤条件的情况
        })
        .single("default-value")
        .onErrorReturn(Throwable::getLocalizedMessage)
        .subscribe(s -> {
            System.out.println("接收到->" + s);
        });
复制代码

の結果

发射 ->task-1
发射 ->task-2
接收到->default
复制代码

ブロッキング方法でシリアル化する(非推奨)

blockingGetスレッドを一時停止するのではなくブロックするブロッキングワーカースレッドを使用して、スレッドが完了するまで他のシステムリソースがスレッドを使用できないようにします。

これはのコルーチンと非常に似Kotlinていますが、コルーチンは非ブロッキングです。

String str1 = single1.subscribeOn(Schedulers.from(executors)).blockingGet();
if (!"success".equals(str1)) {
    single2.subscribeOn(Schedulers.from(executors))
            .subscribe(System.out::println);
}
复制代码

結果:

发射 ->task-1
发射 ->task-2
task-2

复制代码

おすすめ

転載: juejin.im/post/7119443402046832670