如何在使用Rx开始第二次之前等待第一次请求完成?

时间:2017-06-24 14:42:34

标签: android rx-java rx-android

我有一个带回调的异步方法UserControl。它从我的应用程序的不同类中多次调用。我需要这个电话一个接一个地开始,而不是同时开始。

我想用Rx实现它。像这样:

makeRequest()

但是现在所有请求都是并行的。我需要在这里添加什么来逐个运行请求?

1 个答案:

答案 0 :(得分:1)

根据评论,您在这里分开了流和请求。执行请求的每个客户端都期望来自请求的结果。但是没有允许并行运行的请求,在这种情况下,我认为最简单的方法是将Scheduler限制为应用程序全局后台顺序线程执行程序,即:

Schedulers.from(Executors.newSingleThreadExecutor())

在你的应用程序的某个地方提供这个单线程Executor,当然,每个请求流将使用相同的对象,这是非常重要的:

private final Scheduler singleThreadScheduler = Schedulers.from(Executors.newSingleThreadExecutor());

public void execute() { // This method called many times from another classes
    Observable.just(true)
            .map(o -> {
                internalExecute();
                return o;
            })
            .subscribeOn(singleThreadScheduler)
            .subscribe();
}

private void internalExecute() { // This method should called only when previous call was finished
    makeRequest(this::onRequestFinished);
}

private void onRequestFinished() {
    //NOTE: you should make sure that the callback execute where you need it (main thread?)

    // here is I handle request finish
}

除此之外,您不会向客户端公开Observable,而是使用回调机制,您可以通过execute()返回Observable来进一步利用被动方法。 (并享受Obesrvable s的组合,运营商,正确使用observeOn / subscribeOn,使用onError进行错误处理,处理/取消订阅等等),因为您需要使用async api,您可以使用fromEmitter() / create()(在较新的RxJava1版本中),阅读更多here

 private final Scheduler singleThreadScheduler = Schedulers.from(Executors.newSingleThreadExecutor());

public Observable<Result> execute() { // This method called many times from another classes
    return Observable.fromEmitter(new Action1<Emitter<? extends Object>>() {
        @Override
        public void call(Emitter<?> emitter) {
            emitter.setCancellation(() -> {
                //cancel request on unsubscribing
            });
            makeRequest(result -> {
                emitter.onNext(result);
            });
        }
    })
            .subscribeOn(singleThreadScheduler)
}