我正在尝试理解RxJava,我确信这个问题是无意义的...我使用RxJava这个代码:
public Observable<T> getData(int id) {
if (dataAlreadyLoaded()) {
return Observable.create(new Observable.OnSubscribe<T>(){
T data = getDataFromMemory(id);
subscriber.onNext(data);
});
}
return Observable.create(new Observable.OnSubscribe<T>(){
@Override
public void call(Subscriber<? super String> subscriber) {
T data = getDataFromRemoteService(id);
subscriber.onNext(data);
}
});
}
Run Code Online (Sandbox Code Playgroud)
并且,例如,我可以这样使用它:
Action1<String> action = new Action<String>() {
@Override
public void call(String s) {
//Do something with s
}
};
getData(3).subscribe(action);
Run Code Online (Sandbox Code Playgroud)
而另一个回调实现Runnable:
public void getData(int id, MyClassRunnable callback) {
if (dataAlreadyLoaded()) {
T data = getDataFromMemory(id);
callback.setData(data);
callback.run();
} else {
T data = getDataFromRemoteService(id);
callback.setData(data);
callback.run();
}
}
Run Code Online (Sandbox Code Playgroud)
我会这样用它:
getData(3, new MyClassRunnable()); //Do something in run method
Run Code Online (Sandbox Code Playgroud)
哪些是差异?为什么第一个更好?
问题不在于框架本身,而在于范式.我试图了解被动的用例.
我感谢任何帮助.谢谢.
首先,您的RxJava版本要比它需要的复杂得多.这是一个更简单的版本:
public Observable<T> getData(int id) {
return Observable.fromCallable(() ->
dataAlreadyLoaded() ? getDataFromMemory(id) : getDataFromRemoteService(id)
);
}
Run Code Online (Sandbox Code Playgroud)
无论如何,您提出的问题是如此微不足道,以至于两种解决方案之间没有明显区别.这就像询问哪一个更适合分配整数值 - var = var + 1或者var++.在这种特殊情况下它们是相同的,但是当使用赋值时,还有更多的可能性(添加除1以外的值,减去,乘以,除以,考虑其他变量等).
那么你可以用反应来做什么呢?我喜欢reactivex网站上的摘要:
轻松创建事件流或数据流.对于单个数据而言,这并不是那么重要,但是当您拥有数据流时,范例会更有意义.
使用类似查询的运算符编写和转换流.在上面的示例中,没有运算符和单个流.运算符允许您以方便的方式转换数据,并且组合多个回调比组合多个回调要困难得多Observables.
订阅任何可观察的流以执行副作用.你只是在听一个单一的事件.Reactive非常适合收听多个事件.它也适用于错误处理等事项 - 您可以创建一系列长事件,但任何错误都会转发给最终订阅者.
让我们看一个更具体的例子,它有一个更具吸引力的例子:验证电子邮件和密码.你有两个文本字段和一个按钮.您希望在输入电子邮件(假设.*@.*)和密码(至少8个字符)后启用该按钮.
我有两个Observables代表用户当前在文本字段中输入的内容:
Observable<String> email = /* you figure this out */;
Observable<String> password = /* and this, too */;
Run Code Online (Sandbox Code Playgroud)
为了验证每个输入,我可以将输入映射String到true或false.
Observable<Boolean> validEmail = email.map(str -> str.matches(".*@.*"));
Observable<Boolean> validPw = password.map(str -> str.length() >= 8);
Run Code Online (Sandbox Code Playgroud)
然后我可以将它们组合起来以确定是否应该启用该按钮:
Observable.combineLatest(validEmail, validPw, (b1, b2) -> b1 && b2)
.subscribe(enableButton -> /* enable button based on bool */);
Run Code Online (Sandbox Code Playgroud)
现在,每次用户在任一文本字段中键入新内容时,按钮的状态都会更新.我已经设置了逻辑,以便按钮只响应文本字段的状态.
这个简单的例子并未显示所有内容,但它显示了在您通过简单订阅后事情变得更加有趣.显然,你可以在没有反应范式的情况下做到这一点,但是对于被动运算符来说它更简单.