繁体   English   中英

获取 Observable 的最新值并立即发出

[英]Get the latest value of an Observable and emit it immeditely

我正在尝试获取给定Observable的最新值,并在调用后立即发出。 以下面的代码为例:

return Observable.just(myObservable.last())
    .flatMap(myObservable1 -> {
        return myObservable1;
    })
    .map(o -> o.x) // Here I want to end up with a T object instead of Observable<T> object

这不起作用,因为这样做flatMap将发出myObservable1 ,而myObservable1又必须发出才能到达map 我不知道这样做是否可能。 有没有人知道如何实现这个目标? 谢谢

last()方法在这里没有任何帮助,因为它等待 Observable 终止以提供最后发出的项目。

假设您无法控制发出的 observable,您可以简单地创建一个BehaviorSubject并将其订阅到发出您想要收听的数据的 observable,然后订阅创建的主题。 由于Subject既是Observable又是Subscriber你会得到你想要的。

我认为(现在没有时间检查)您可能必须手动取消订阅原始 observable,因为BehaviorSubject一旦他的所有订阅者取消订阅就不会自动取消订阅。

像这样的东西:

BehaviorSubject subject = new BehaviorSubject();
hotObservable.subscribe(subject);
subject.subscribe(thing -> {
    // Here just after subscribing 
    // you will receive the last emitted item, if there was any.
    // You can also always supply the first item to the behavior subject
});

http://reactivex.io/RxJava/javadoc/rx/subjects/BehaviorSubject.html

在 RxJava 中,subscriber.onXXX 被称为异步的。这意味着如果你的 Observable 在新线程中发射项目,你永远无法获得返回前的最后一个项目,除非你阻塞线程并等待项目。但如果 Observable 同步发射项目并且您不会通过 subscribeOn 和 observOn 更改它的线程,例如代码:

Observable.just(1,2,3).subscribe();

在这种情况下,您可以通过执行以下操作来获取最后一项:

Integer getLast(Observable<Integer> o){
    final int[] ret = new int[1];
    Observable.last().subscribe(i -> ret[0] = i);
    return ret[0];
}

这样做是个坏主意。RxJava 更喜欢你用它来做异步工作。

您在这里真正想要实现的是将异步任务转换为同步任务。

有几种方法可以实现它,每种方法都有其优点和缺点:

  • 使用toBlocking() - 这意味着这个线程将被阻塞,直到流结束,为了只获得一个项目,只需使用first()因为它会在一个项目交付后完成。 假设你的整个流是Observable<T> getData(); 那么立即获取最后一个值的方法将如下所示:

public T getLastItem(){ return getData().toBlocking().first(); }

请不要使用last() ,因为它会等待流完成,然后才会发出最后一项。

如果你的流是一个网络请求并且它没有得到任何项目,这会阻塞你的线程!,所以只有当你确定有一个项目立即可用时才使用它(或者如果你真的想要一个块......)

  • 另一种选择是简单地缓存最后一个结果,如下所示:

    getData().subscribe(t-> cachedT = t;) //在代码的某个地方,它会一直保存最后一个交付的项目 public T getLastItem(){ return cachedT; }

如果在您请求它时没有发送任何项目,您将获得 null 或您设置的任何初始值。 这种方法的问题是订阅阶段可能发生在 get 之后,如果在 2 个不同的线程中使用,可能会产生竞争条件。

暂无
暂无

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

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