RxJava:如何使用LatestFrom进行模拟?

时间:2015-02-18 09:52:11

标签: rx-java

根据文档,Java实现中缺少withLatestFrom(与combineLatest略有不同)。关于如何效仿的​​任何想法? enter image description here

2 个答案:

答案 0 :(得分:2)

a作为主要观察点,b作为'最新来自'可观察的,这个伪java8 lambda应该做你想要的:

a.publish(a' -> b.switchMap(y -> a'.map(x -> x + y)))

这首先将a发布为a',这允许在不重新启动流的情况下重复订阅它。然后,每次发出b的新项目时,它都会重新订阅正在进行的a流,该流将b的最新输出与a的每个输出相结合。

您可以轻松地将其包装为RxJava Transformer的实现,就像这样(也是半伪的,所以请检查我的语法):

 public class WithLatestFrom<T, U, V> implements Transformer<T, V> {
   private final Func2<T, U, V> function;
   private final Observable<U> latest;

   private WithLatestFrom<T, U, V>(final Observable<U> latest, Func2<T, U, V> function) {
     this.function = function;
     this.latest = latest;
   }

   public static <T, U, V> WithLatestFrom<T, U, V> with(
       final Observable<U> latest, Func2<T, U, V> function) {
     return new WithLatestFrom<T, U, V>(latest, function);
   }

   @Override
   public Observable<V> call(final Observable<T> source) {
     return source.publish((publishedSource) -> latest.switchMap((y) ->
         publishedSource.map((x) -> function.call(x, y)));
   }

}

然后您可以在代码中重复使用它,如:

a.compose(WithLatestFrom.with(b, (x, y) -> x + y));

答案 1 :(得分:0)

一些非常简单和天真的实现是:

@SuppressWarnings("unchecked")
public static <T, U, V> Observable<T> combineLatestFrom(
  Observable<U> o1,
  Observable<V> o2,
  Func2<U, V, T> f) {

    final Object nothing = new Object();
    return Observable.create(s -> {

        AtomicReference<V> val2 = new AtomicReference<V>((V) nothing);

        o1.subscribe(v -> {
          val2.getAndUpdate(current -> {
            if (current != nothing) {
              s.onNext(f.call(v, current));
            }
            return current;
          });   
        }, s::onError, s::onCompleted);

        o2.subscribe(val2::set, s::onError);

    });
}

这个方法可以这样使用:

combineLatestFrom(numbers, letters, (n, l) -> n + l)
  .subscribe(System.out::println);

如果在这里数字和字母是大理石图中的Observables - &gt;结果将符合预期。