Introduction to RxJava3 Single
The code in this article is tested in the IntellJ environment, you can directly copy it and run it
IntellJ creates a new Gradle project and introduces dependencies
implementation "io.reactivex.rxjava3:rxjava:3.0.0"
In RxJava, Single can describe an event that only sends an event value once, such as a network request. It has two subscribable interfaces, onSuccess and onError, which will automatically unsubscribe when any interface is triggered.
//创建Single
Single<String> single = Single.create(emitter -> {
emitter.onSuccess("ok");
});
//订阅single
single.subscribe(System.out::println);
复制代码
Multiple Singles are executed serially
First create multiple Singles
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);
});
}
复制代码
Declare multiple Single tasks
Single<String> single1 = task1();
Single<String> single2 = task2();
复制代码
Worker threads, usually used directly Schedulers.io()
, here a thread pool is used to print logs in a thread
Executor executor = Executors.newSingleThreadExecutor();
复制代码
Scenario 1: Execute serially and receive each result
Single.concat(single1, single2)
.subscribeOn(Schedulers.from(executors))
.subscribe(s -> {
System.out.println("接收到->" + s);
});
复制代码
Results of the:
发射 ->task-1
接收到->task-1
发射 ->task-2
接收到->task-2
复制代码
Scenario 2: According to the result of the previous single, determine whether to execute the latter one
If the data is read from the database cache first, if there is no request from the network
Single.concat(single1, single2)
.subscribeOn(Schedulers.from(executors))
.takeUntil(s -> {
return !"".equals(s);
})
.filter(s -> {
return !"".equals(s);
})
.subscribe(s -> {
System.out.println("接收到->" + s);
});
复制代码
Results of the:
发射 ->task-1
接收到->task-1
复制代码
takeUntil
The AND filter
operator is used here to implement conditional judgment and filter unwanted request results.
takeUntil
When the condition returns true, the next Single is not executed, and the result is returned directly; if takeUntil
the condition returns false, the emitted value filter
is filtered out in the operator, and the execution of the next Single is continued.
Provide default return value and exception handling
If the execution results of multiple singles are filtered, the subscriber will not receive any value, and a default return value can be provided at this time;
Use single()
an operator to provide a default return value when the result is empty
Handling exceptions with onErrorReturn()
operators
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);
});
复制代码
Results of the
发射 ->task-1
发射 ->task-2
接收到->default
复制代码
Serialize in a blocking way (not recommended)
Use a blockingGet
blocking worker thread, which blocks rather than suspends the thread, making it unavailable to other system resources until the thread completes.
This is very similar Kotlin
to the coroutine in , but the coroutine is non-blocking.
String str1 = single1.subscribeOn(Schedulers.from(executors)).blockingGet();
if (!"success".equals(str1)) {
single2.subscribeOn(Schedulers.from(executors))
.subscribe(System.out::println);
}
复制代码
Results of the:
发射 ->task-1
发射 ->task-2
task-2
复制代码