Java 获取可观察对象的最新值并立即发出

Java 获取可观察对象的最新值并立即发出,java,rx-java,reactive-programming,rx-android,Java,Rx Java,Reactive Programming,Rx Android,我试图获取给定的可观测的的最新值,并让它发出 一接到电话就马上。以下面的代码为例: 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>

我试图获取给定的可观测的
的最新值,并让它发出
一接到电话就马上。以下面的代码为例:

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
返回Observable.just(myObservable.last())
.flatMap(myObservable1->{
返回myObservable1;
})
.map(o->o.x)//这里我想以一个T对象而不是一个可观察对象结束
这不起作用,因为通过执行此操作,
flatMap
将发出
myObservable1
,而myObservable1反过来将具有 要发射以到达
贴图
。 我不知道这样做是否可能。有人知道如何实现这个目标吗?谢谢

last()
方法在这里不会有任何帮助,因为它会等待可观察对象终止以提供最后发出的项

假设您无法控制发射的可观察对象,您可以简单地创建一个
行为主体
,并将其订阅给发射您想要收听的数据的可观察对象,然后订阅所创建的主体。由于
主题
既是
可观察的
又是
订户
,您将得到您想要的

我认为(现在没有时间检查)您可能必须手动取消订阅原始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
});
Integer getLast(Observable<Integer> o){
    final int[] ret = new int[1];
    Observable.last().subscribe(i -> ret[0] = i);
    return ret[0];
}

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

Observable.just(1,2,3).subscribe();
在这种情况下,您可以通过如下操作获取最后一项:

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
});
Integer getLast(Observable<Integer> o){
    final int[] ret = new int[1];
    Observable.last().subscribe(i -> ret[0] = i);
    return ret[0];
}
整数getLast(可观测的o){
最终整数[]ret=新整数[1];
Observable.last().subscribe(i->ret[0]=i);
返回ret[0];
}

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

你真正想要实现的是接受一个异步任务并将其转换为一个同步任务

实现这一目标有几种方法,每种方法都有其优缺点:

  • 使用-这意味着该线程将被阻塞,直到流完成,以便只获取一个项目,只需使用,因为一旦交付一个项目,它将完成。 假设您的整个流是
    可观察的getData()
    然后,将立即获取最后一个值的方法将如下所示:
public T getLastItem(){
返回getData().toBlocking().first();
}

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

如果您的流是一个网络请求,但尚未获取任何项目,这将阻止您的线程!,因此,只有当您确定有一个项目立即可用时(或者如果您真的想要一个区块…),才可以使用它

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

    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
    });
    
    Integer getLast(Observable<Integer> o){
        final int[] ret = new int[1];
        Observable.last().subscribe(i -> ret[0] = i);
        return ret[0];
    }
    
    getData().subscribe(t->cachedT=t;)//在代码中的某个地方,它将继续保存最后交付的项目 公共T getLastItem(){ 返回cachedT; }

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

您在谈论什么是可观察的?你所说的最新是什么意思?
myObservable
是一种热可观测物,它以不规则的间隔发射例如:“1”、“2”、“3”。我想做的是,在我到达
返回方向时,能够获得
myObservable
最新值(在本例中为“3”),myObservable是热的还是冷的?看起来你仍然在以命令式(而不是反应式)的方式思考。你能给我一个更大的视角吗?关键是,通常情况下,您会基于其他可观察对象创建可观察对象。您可以基于myObservable创建lastObservable,它将被阻止,直到myObservable结束,然后发出最后一个值。除了subscribe这样的端点之外,这些流“管道”是没有出路的。我曾经在RxJava谷歌小组上问过一个类似的问题——也许Ben的答案对你有帮助:我在这里的代码理解上有困难;getLastItem应用于哪个类?getData()函数的详细信息是什么?getData只是强调您正在使用的流。您可以将其替换为您正在使用的observable,比如原始示例observable myObservable中的myObservable;然后myObservable.toBlocking().first()将在第一个项目到达后提供给您。