了解RxJava:Runnable回调之间的差异

时间:2016-01-27 11:13:45

标签: callback rx-java

我试图理解RxJava,我确定这个问题是无意义的...我使用RxJava这个代码:

{rabbitmq_tracing, 
    [{username, "user"},
     {password, "pass"}]
 },

例如,我可以这样使用它:

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);
        }
    });
}

另一个回调实现了Action1<String> action = new Action<String>() { @Override public void call(String s) { //Do something with s } }; getData(3).subscribe(action);

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();
    }
}

有哪些区别?为什么第一个更好?

问题不在于框架本身,而在于范式。我试图了解被动的用例。

我感谢任何帮助。感谢。

1 个答案:

答案 0 :(得分:5)

首先,您的RxJava版本要比它需要的复杂得多。这是一个更简单的版本:

public Observable<T> getData(int id) {
  return Observable.fromCallable(() ->
      dataAlreadyLoaded() ? getDataFromMemory(id) : getDataFromRemoteService(id)
  );
}

无论如何,您提出的问题是如此微不足道,以至于两种解决方案之间没有明显区别。这就像询问哪一个更适合分配整数值 - var = var + 1var++。在这种特殊情况下,它们是相同的,但在使用赋值时,还有更多的可能性(添加除1之外的值,减去,乘以,除以,考虑其他变量等)。

那么你可以做什么反应?我喜欢reactivex's website上的摘要:

  1. 轻松创建事件流或数据流。对于单个数据,这不是很重要,但是当您拥有数据流时,范例会做得更多感。

  2. 使用类似查询的运算符编写和转换流。在上面的示例中,没有运算符和单个流。运算符允许您以方便的方式转换数据,并且组合多个回调比组合多个Observables要困难得多。

  3. 订阅任何可观察的流以执行副作用。您只是在收听单个事件。 Reactive非常适合收听多个事件。它也适用于错误处理等事项 - 您可以创建一长串事件,但任何错误都会转发给最终订阅者。

  4. 让我们看一个更具体的例子,其中有一个更具吸引力的例子:验证电子邮件和密码。您有两个文本字段和一个按钮。您希望在输入电子邮件(让我们说.*@.*)和密码(至少8个字符)后启用该按钮。

    我有两个Observables代表用户当前在文本字段中输入的内容:

    Observable<String> email = /* you figure this out */;
    Observable<String> password = /* and this, too */;
    

    为了验证每个输入,我可以将<{1}} <{1}}映射Stringtrue

    false

    然后我可以合并以确定是否应该启用该按钮:

    Observable<Boolean> validEmail = email.map(str -> str.matches(".*@.*"));
    Observable<Boolean> validPw = password.map(str -> str.length() >= 8);
    

    现在,每次用户在任一文本字段中键入新内容时,按钮的状态都会更新。我已经设置了逻辑,以便按钮对文本字段的状态做出反应

    这个简单的例子并没有显示出来,但它显示了在你通过一个简单的订阅后事情变得更有趣。显然,你可以在没有反应范式的情况下做到这一点,但对于被动算子来说它更简单。