简体   繁体   English

使用RxJava执行请求或订阅结果

[英]Execute request or subscribe to the result with RxJava

I am trying to implement the following logic with RxJava: 我正在尝试使用RxJava实现以下逻辑:

  1. Execute server request if I don't have value locally 如果我在本地没有价值,请执行服务器请求
  2. Provide result to the subscriber 提供结果给订户
  3. If the request is running do not create a second one, but subscribe to the result of the running request. 如果请求正在运行,请不要创建第二个请求,而是订阅正在运行的请求的结果。

The following solution partially solves the problem: 以下解决方案部分解决了该问题:

private final ExecutorService executor = Executors.newSingleThreadExecutor();

private  Observable<T> getValue(){
    if(storage.getValue() == null) {
        Future<T> futureValue = executor.submit(new Callable<T>() {
            @Override
            public T call() throws Exception {
                return getValueFromStorageOrBackend();
            }
        });
        return Observable.from(futureValue);
    } else {
        return Observable.just(storage.getValue());
    }
}

private String getValueFromStorageOrBackend() {
    final String currentValue = storage.getValue();
    if (currentValue == null) {
        Response response = backend.requestValue();
        storage.setValue(response.getValue());

        return response.getValue();
    }

    return currentValue;
}

Is there an elegant pure RxJava solution for this? 是否有一个优雅的纯RxJava解决方案?

One of the simpler ways to do this is via AsyncSubject + a compare-and-set loop: 一种简单的方法是通过AsyncSubject +一个“比较并设置”循环:

final AtomicReference<AsyncSubject<T>> subjectRef = new AtomicReference<>();

public Observable<T> get() {
    for (;;) {
        AsyncSubject<T> subject = subjectRef.get();
        if (subject != null) {
            return subject;
        }
        AsyncSubject<T> next = AsyncSubject.create();
        if (subjectRef.compareAndSet(null, next)) {
            Observable.just(1).map(ignored -> {
                // your computation here
                return 2; // the result
            }).subscribeOn(Schedulers.io()).subscribe(subject);
            return;
        }
    }
}

I almost forgot, an even more simple way is to use cache : 我差点忘了,更简单的方法是使用cache

Observable
.just(1)
.subscribeOn(Schedulers.io())
.map(ignored -> {
    // computation here
    return 2;
}).cache();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM