我想要一个调用某个函数的Single,然后用函数返回的值完成。
以下是类似的内容:
Single.fromCallable(this::func);
问题在于每次添加订阅者时都会调用:: func。因此,如果这个:: func计算单个将返回3到第三个订阅者的调用。
我认为这是一个问题,因为,如果这个:: func是一个长时间运行的操作。
我不明白,这是否意味着Single :: onComplete被调用了两次?我认为这是不可能的,而且没有意义,因为,有什么东西可以完成两次?
既然我是Android程序员Single :: fromFuture在这里不起作用,还有其他选择吗?
我将通过以下示例演示我的问题:
class SingleFromCallableTest {
int funcCalls = 0;
int func(){
return funcCalls++;
}
@Test
public void run(){
Single<Integer> source = Single.fromCallable(this::func);
source.subscribe(System.out::println); // prints 1
source.subscribe(System.out::println); // prints 2
}
}
IMO,第二个订阅者不应该被调用,因为Single应该只在IMO成功一次。
就像SingleSubject一样,一旦你调用onSuccess,它就无法再次成功。
如果Single.fromCallable
按照它认为应该的方式工作,那么在前一个例子中,source
甚至可以在第一个订阅者订阅之前完成,这意味着,只有以下订阅方式会有意义的:
Single.fromCallable(this::func).subscribe(System.out.println);
但实际上,即便如此,也许有可能不会捕捉到单身的价值,也许这是不可能的。
答案 0 :(得分:2)
方法#fromCallable是一个工厂,每次都会返回一个新的Single。在每次订阅时,您将订阅一个新的单身。因此,将为每个订户调用该函数。如果要缓存该值,则应使用#cache运算符。请看看提供的两个测试。
测试&#39; notCached&#39;将为每个订阅调用该函数。测试&#39;缓存&#39;只会调用一次该函数。如果要共享结果,只需使用#cache运算符重新使用create Single#fromCallable。
环境
dependencies {
compile 'io.reactivex.rxjava2:rxjava:2.1.6'
compile 'org.mockito:mockito-core:2.11.0'
testCompile("org.junit.jupiter:junit-jupiter-api:5.0.0")
testRuntime("org.junit.jupiter:junit-jupiter-engine:5.0.0")
测试
@Test
void notCached() throws Exception {
Callable<Integer> mock = mock(Callable.class);
when(mock.call()).thenReturn(10);
Single<Integer> integerSingle = Single.fromCallable(mock);
Disposable subscribe1 = integerSingle.subscribe();
Disposable subscribe2 = integerSingle.subscribe();
verify(mock, times(2)).call();
}
@Test
void cached() throws Exception {
Callable<Integer> mock = mock(Callable.class);
when(mock.call()).thenReturn(10);
Single<Integer> integerSingle = Single.fromCallable(mock).cache();
Disposable subscribe1 = integerSingle.subscribe();
Disposable subscribe2 = integerSingle.subscribe();
Disposable subscribe3 = integerSingle.subscribe();
Disposable subscribe4 = integerSingle.subscribe();
verify(mock, times(1)).call();
}