我希望能够订阅publishsubject并等待结果,但不能超过1分钟。
问题是,如果我这样做
publishsubject.timeout(1, TimeUnit.MINUTES).subscribe({result -> ... }, {error -> ... } )
即使在此之前我成功获得了结果,我总是会出错。如何正确实施这种方法?
答案 0 :(得分:1)
在下面的示例中,我显示timeout
的工作方式。对于每次发射,都会启动一个新的超时,如果在超时运行之前有新项目到达,则重新设置超时,否则将引发异常。
在示例中,我们可以在控制台上看到1、2、3的打印,并且由于超时异常而结束,因为第4个项目不在3之后的200毫秒之内。
正如我在下面的评论中所述,如果您知道何时可以终止publishSubject
,则可以避免这种情况。例如,在第三项之后使用take
,takeUntil
或致电publishSubject.onComplete()
。
@Test
public void timeout() throws InterruptedException {
PublishSubject<Object> publishSubject = PublishSubject.create();
Observable<Object> timeout = publishSubject.timeout(200, TimeUnit.MILLISECONDS);
timeout
.subscribe(
e -> System.out.println(e),
error -> System.out.println("ERROR: " + error),
() -> System.out.println("complete")
);
sleep(50);
publishSubject.onNext(1);
sleep(150);
publishSubject.onNext(2);
sleep(199);
publishSubject.onNext(3);
sleep(201);
publishSubject.onNext(4);
Thread.sleep(2000);
}
答案 1 :(得分:1)
您很可能会收到超时异常,因为timeout
要求您的来源在指定的时间范围内持续生产商品或完成商品。因此,如果您仅向onNext
发送一个PublishSubject
信号,并且再也没有收到信号,则由于缺少第二个onNext
呼叫,您将超时。
因此,如果您想要一项,请使用take
(在timeout
之前或之后):
publishsubject
.timeout(1, TimeUnit.MINUTES)
.take(1)
.subscribe(result -> { /* ... */ }, error -> { /* ... */ } )