前言
filter 用于对发布的元素进行过滤。
一、filter
1、示例
@Test
public void filter() {
Flux.range(0, 5).filter(i -> i > 2).subscribe(System.out::println);
}
2、原理
(1)FluxFilterFuseable
创建 FilterFuseableConditionalSubscriber 或 FilterFuseableSubscriber
@Override
public CoreSubscriber<? super T> subscribeOrReturn(CoreSubscriber<? super T> actual) {
if (actual instanceof ConditionalSubscriber) {
return new FilterFuseableConditionalSubscriber<>((ConditionalSubscriber<? super T>) actual,
predicate);
}
return new FilterFuseableSubscriber<>(actual, predicate);
}
(2)FilterFuseableSubscriber
@Override
public boolean tryOnNext(T t) {
//请求完成,丢弃元素
if (done) {
Operators.onNextDropped(t, this.ctx);
return false;
}
boolean b;
//校验条件
try {
b = predicate.test(t);
}
catch (Throwable e) {
Throwable e_ = Operators.onNextError(t, e, this.ctx, s);
if (e_ != null) {
onError(e_);
}
Operators.onDiscard(t, this.ctx);
return false;
}
//条件通过,将元素发送给订阅者
if (b) {
actual.onNext(t);
return true;
}
//条件不通过,丢弃元素
Operators.onDiscard(t, this.ctx);
return false;
}
二、filterWhen
传入 Function 将T转换成 Publisher<Boolean> ,根据返回的boolean来过滤元素
1、示例
@Test
public void filterWhen() {
Flux.range(0, 5)
.filterWhen(i -> Mono.just(i).map(v -> v != 2))
.subscribe(System.out::println);
}
2、原理
(1)FluxFilterWhen
创建 FluxFilterWhenSubscriber
@Override
public CoreSubscriber<? super T> subscribeOrReturn(CoreSubscriber<? super T> actual) {
return new FluxFilterWhenSubscriber<>(actual, asyncPredicate, bufferSize);
}
(2)FluxFilterWhenSubscriber
@Override
public void onNext(T t) {
long pi = producerIndex;
int m = toFilter.length() - 1;
int offset = (int)pi & m;
//将元素存入 toFilter
toFilter.lazySet(offset, t);
producerIndex = pi + 1;
//具体的逻辑
drain();
}
(3)drain()
void drain() {
if (WIP.getAndIncrement(this) != 0) {
return;
}
int missed = 1;
int limit = Operators.unboundedOrLimit(bufferSize);
long e = emitted;
long ci = consumerIndex;
int f = consumed;
int m = toFilter.length() - 1;
Subscriber<? super T> a = actual;
for (;;) {
long r = requested;
while (e != r) {
if (cancelled) {
clear();
return;
}
boolean d = done;
int offset = (int)ci & m;
T t = toFilter.get(offset);
boolean empty = t == null;
//校验是否请求数据结束或元素是否为 null
if (d && empty) {
Throwable ex = Exceptions.terminate(ERROR, this);
if (ex == null) {
a.onComplete();
} else {
a.onError(ex);
}
return;
}
//值是 null,或者值已经处理过 被设置为了 null,退出当前循环,然后继续处理下一个元素
if (empty) {
break;
}
int s = state;
//初始状态
if (s == STATE_FRESH) {
Publisher<Boolean> p;
try {
//获取到 Publisher<Boolean>
p = Objects.requireNonNull(asyncPredicate.apply(t), "The asyncPredicate returned a null value");
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
Exceptions.addThrowable(ERROR, this, ex);
p = null; //discarded as "old" below
}
if (p != null) {
if (p instanceof Callable) {
Boolean u;
try {
u = ((Callable<Boolean>)p).call();
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
Exceptions.addThrowable(ERROR, this, ex);
u = null; //triggers discard below
}
if (u != null && u) {
a.onNext(t);
e++;
}
else {
Operators.onDiscard(t, ctx);
}
} else {
//创建 FilterWhenInner ,并将当前类对象 FluxFilterWhenSubscriber 作为 parent 传入
FilterWhenInner inner = new FilterWhenInner(this, !(p instanceof Mono));
if (CURRENT.compareAndSet(this,null, inner)) {
state = STATE_RUNNING;
//FilterWhenInner 作为 Publisher<Boolean> 的订阅者
p.subscribe(inner);
break;
}
}
}
T old = toFilter.getAndSet(offset, null);
Operators.onDiscard(old, ctx);
ci++;
if (++f == limit) {
f = 0;
upstream.request(limit);
}
} else
if (s == STATE_RESULT) {
//有值的状态
Boolean u = innerResult;
innerResult = null;
//条件成立,将元素传递给订阅者
if (u != null && u) {
a.onNext(t);
e++;
}
else {
Operators.onDiscard(t, ctx);
}
//清理值
toFilter.lazySet(offset, null);
ci++;
if (++f == limit) {
f = 0;
upstream.request(limit);
}
//恢复初始状态
state = STATE_FRESH;
} else {
break;
}
}
if (e == r) {
if (cancelled) {
clear();
return;
}
boolean d = done;
int offset = (int)ci & m;
T t = toFilter.get(offset);
boolean empty = t == null;
if (d && empty) {
Throwable ex = Exceptions.terminate(ERROR, this);
if (ex == null) {
a.onComplete();
} else {
a.onError(ex);
}
return;
}
}
int w = wip;
if (missed == w) {
consumed = f;
consumerIndex = ci;
emitted = e;
missed = WIP.addAndGet(this, -missed);
if (missed == 0) {
break;
}
} else {
missed = w;
}
}
}
(4)FilterWhenInner
上面创建了 FilterWhenInner,在 FilterWhenInner 中 的 onNext() 方法中会处理 Publisher<Boolean> 返回的 boolean 值
@Override
public void onNext(Boolean t) {
if (!done) {
if (cancelOnNext) {
sub.cancel();
}
done = true;
//设置boolean值
parent.innerResult(t);
}
}
(5)innerResult()
void innerResult(Boolean item) {
//boolean 值
innerResult = item;
//修改状态,有了结果的状态
state = STATE_RESULT;
clearCurrent();
drain();
}