我有一些传统的非RX代码通过生成一个新线程来完成一些网络工作。 当工作完成时,它会在回调上调用一个方法。
我无法控制此代码运行的线程。这是遗产,它本身会产生一个新的Thread
。
这可以简化为:
interface Callback {
void onSuccess();
}
static void executeRequest(String name, Callback callback) {
new Thread(() -> {
try {
System.out.println(" Starting... " + name);
Thread.sleep(2000);
System.out.println(" Finishing... " + name);
callback.onSuccess();
} catch (InterruptedException ignored) {}
}).start();
}
我想将其转换为RX Completable
。为此,我使用Completable#create()
。
CompletableEmitter
的实现调用executeRequest
传递Callback
的实现,该请求在请求完成时发出信号。
订阅时我还会打印日志跟踪以帮助我调试。
static Completable createRequestCompletable(String name) {
return Completable.create(e -> executeRequest(name, e::onComplete))
.doOnSubscribe(d -> System.out.println("Subscribed to " + name));
}
这可以按预期工作。 Completable
仅在“请求”完成并且调用回调之后才完成。
问题是,当在trampoline
调度程序中订阅这些补充表时,它不会在订阅第二个请求之前等待第一个请求完成。
此代码:
final Completable c1 = createRequestCompletable("1");
c1.subscribeOn(Schedulers.trampoline()).subscribe();
final Completable c2 = createRequestCompletable("2");
c2.subscribeOn(Schedulers.trampoline()).subscribe();
输出:
Subscribed to 1
Starting... 1
Subscribed to 2
Starting... 2
Finishing... 1
Finishing... 2
如您所见,即使我正在订阅Completable
,它也会在第一个Completable
完成之前订阅第二个trampoline
。
我想排队completables
,以便第二个等待第一个完成,输出:
Subscribed to 1
Starting... 1
Finishing... 1
Subscribed to 2
Starting... 2
Finishing... 2
我确定问题与工作线程中的工作有关。如果Completable
的实现没有生成新线程,它将按预期工作。
但这是遗留代码,而我正在尝试做的是将其调整为RX而不进行修改。
注意:请求在程序的不同点执行 - 我不能使用andThen
或concat
来实现序列化执行。
答案 0 :(得分:1)
我设法通过使用Completables
明确阻止订阅Thread
来顺序执行Latch
。
但我不认为这是在RX中这样做的惯用方法,我仍然不明白为什么我需要这样做,并且在Completable
完成之前线程不会被阻止。
static Completable createRequestCompletable(String name) {
final CountDownLatch latch = new CountDownLatch(1);
return Completable.create(e -> {
executeRequest(name, () -> {
e.onComplete();
latch.countDown();
});
latch.await();
})
.doOnSubscribe(disposable -> System.out.println("Subscribed to " + name));
}