我正在尝试Java 9中的一些新功能。所以我组织了一个测试,让一个发布者以给定的速率发出数字。我还实现了一个订阅者来收听这些出版物,然后将它们打印到控制台。
虽然我可能不完全了解如何使用此Api,因为onNext()
方法不打印任何内容而getLastItem()
仅返回0.
似乎有效的唯一部分是正确初始化onSubscribe()
变量的lastItem
。
@Test
public void testReactiveStreams(){
//Create Publisher
SubmissionPublisher<Integer> publisher = new SubmissionPublisher<>();
//Register Subscriber
TestIntegerSubscriber subscriber = new TestIntegerSubscriber();
publisher.subscribe(subscriber);
assertTrue(publisher.hasSubscribers());
//Publish items
System.out.println("Publishing Items...");
List.of(1,2,3,4,5).stream().forEach(i -> {
publisher.submit(i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// blah
}
});
assertEquals(5, subscriber.getLastItem());
publisher.close();
}
private class TestIntegerSubscriber implements Flow.Subscriber<Integer> {
private int lastItem;
@Override
public void onSubscribe(Flow.Subscription subscription) {
System.out.println("Subscribed");
lastItem = 0;
}
@Override
public void onNext(Integer item) {
System.out.println("Received : "+item);
lastItem += 1; // expect increment by 1
assertTrue(lastItem == item);
}
@Override
public void onError(Throwable throwable) {
// nothing for the moment
}
@Override
public void onComplete() {
System.out.println("Completed");
}
public int getLastItem(){
return lastItem;
}
}
有人可以告诉我,我的测试中出错了吗?我希望测试打印这些数字并返回5作为最后一项。
我不得不说我只使用Angular2中的Observables和Subjects,虽然它们似乎更容易理解。
答案 0 :(得分:4)
Flow API实现了一项名为 backpressure (explained here in the context of RxJava)的功能,这意味着发布商不应该通过发布项目而不是处理它们来淹没订阅者。 JDK 9实现的方式是让订阅者从订阅中请求项目。
对于您的测试,TestIntegerSubscriber
应该请求项onSubscription
,让我们说10,并跟踪onNext
被调用的频率,以便它可以请求更多一旦推了10个项目。
我写了a section about the Flow API更详细的内容。它还描述了发布者,订阅者和订阅之间的交互:
Publisher
和Subscriber
。Publisher::subscribe
订阅订阅者。Subscription
并使用它调用Subscriber::onSubscription
,以便订阅者可以存储订阅。Subscription::request
来请求多个项目。Subscriber::onNext
开始将物品交给订阅者。它永远不会发布超过所请求数量的项目。Subscriber::onComplete
或Subscriber::onError
。Subscription::cancel
来切断连接。答案 1 :(得分:0)
我已经做了一些更多的研究,我可以看到代码可以通过在Subscription
实现中添加Subscriber
成员来实现,如下所示:
public class MySubscriber<T> implements Subscriber<T> {
private Subscription subscription;
...
@Override
public void onSubscribe(Flow.Subscription subscription) {
this.subscription = subscription;
System.out.println("Subscribed");
subscription.request(1);
lastItem = 0;
}
...
@Override
public void onNext(Integer item) {
System.out.println("Received : "+item);
lastItem += 1; // expect increment by 1
assertTrue(lastItem == item);
subscription.request(1);
}
其中subscription.request(1);
我认为这意味着我正在使用发布商的1件商品。我不知道......如果有人向我澄清,那实际上会很好。