我已经按照RxJava2 wiki(https://github.com/ReactiveX/RxJava/wiki/Writing-operators-for-2.0#operator-targeting-lift)中的描述实现了FlowableOperator
,除了我在onNext()
操作中执行了类似的操作:
public final class MyOperator implements FlowableOperator<Integer, Integer> {
...
static final class Op implements FlowableSubscriber<Integer>, Subscription {
@Override
public void onNext(Integer v) {
if (v % 2 == 0) {
child.onNext(v * v);
}
}
...
}
}
此运算符是链的一部分,我在其中创建了带有背压降的Flowable
。从本质上讲,它看起来几乎是这样的:
Flowable.<Integer>create(emitter -> myAction(), DROP)
.filter(v -> v > 2)
.lift(new MyOperator())
.subscribe(n -> doSomething(n));
我遇到了以下问题:
doSomething(n)
无法处理即将到来的上游回顾David Karnok的优秀博文http://akarnokd.blogspot.fr/2015/05/pitfalls-of-operator-implementations.html,似乎我需要在request(1)
方法中添加onNext()
。但那是RxJava1 ......
所以,我的问题是:RxJava2中有足够的解决方法来处理我的背压问题吗?或者我的操作员是否必须实施有关Atomics的所有内容,排除https://github.com/ReactiveX/RxJava/wiki/Writing-operators-for-2.0#atomics-serialization-deferred-actions中描述的内容以正确处理我的背压问题?
注意:我添加了request(1)
,它似乎有效。但是我无法弄清楚它是否足够,或者我的操作员是否需要排队排水和原子的棘手问题。
提前致谢!
答案 0 :(得分:1)
FlowableOperator本身是否支持背压?
Subscriber
是为给定的下游Subscriber
调用的接口,应该返回一个新的Subscriber
,它包装下游并调制在一个或两个方向上传递的Reactive Streams事件。背压支持是Function<Subscriber, Subscriber>
实现的责任,而不是这个特定的功能接口。它可能是Subscriber
但是一个单独的命名接口被认为更有用,更不容易出现过载冲突。
需要在onNext()[...]中添加一个请求(1) 但是我无法弄清楚它是否足够,或者我的操作员是否需要排队排水和原子的棘手问题。
是的,你也必须在RxJava 2中这样做。由于RxJava 2 request
不是一个类,它没有v1的方便Subscription
方法。您必须将onSubscribe
保存在upstream.request(1)
中,并在onNext
中的相应路径上致电final class FilterOddSubscriber implements FlowableSubscriber<Integer>, Subscription {
final Subscriber<? super Integer> downstream;
Subscription upstream;
// ...
@Override
public void onSubscribe(Subscription s) {
if (upstream != null) {
s.cancel();
} else {
upstream = s; // <-------------------------
downstream.onSubscribe(this);
}
}
@Override
public void onNext(Integer item) {
if (item % 2 != 0) {
downstream.onNext(item);
} else {
upstream.request(1); // <-------------------------
}
}
@Override
public void request(long n) {
upstream.request(n);
}
// the rest omitted for brevity
}
。对于你的情况,它应该足够了。
我已经使用新的部分更新了wiki,明确解释了这个案例:
https://github.com/ReactiveX/RxJava/wiki/Writing-operators-for-2.0#replenishing
\b([1-9]|[1-5]\d|60)\b
答案 1 :(得分:0)
是的,你必须做那些棘手的事情......
我会避免编写操作符,除非你非常确定你在做什么?使用默认运算符几乎可以实现一切......
编写运算符,类似源(fromEmitter)或类似中间 (flatMap)在RxJava中一直是一项艰巨的任务。有许多 服从的规则,许多情况要考虑,但同时,许多 (合法的)快捷方式,用于构建性能良好的代码。现在写 专门针对2.x的运算符比1.x难10倍。如果 你想利用所有先进的第四代功能 甚至比上面硬2-3倍(总共30倍)。
解释了一些棘手的问题:https://github.com/ReactiveX/RxJava/wiki/Writing-operators-for-2.0