public class FluxHandleMain {
public static void main(String[] args) {
Flux<String> alphabet = Flux.just(-3, 40, 18, 9, 20)
.handle((i, sink) -> {
String letter = alphabet(i);
if (letter != null)
//BiConsumer内部仅可执行一次next操作
sink.next(letter);
});
alphabet.subscribe(System.out::println);
}
public static String alphabet(int letterNumber) {
if (letterNumber < 1 || letterNumber > 26) {
return null;
}
int letterIndexAscii = 'A' + letterNumber - 1;
return "" + (char) letterIndexAscii;
}
}
FluxHandle是一个中间操作(继承InternalFluxOperator),但在功能实现上有点类似于源生产者(SourceProducer).与FluxPeek,FluxMap,FluxFilter相比,主要的差别在HandleSubscriber#onNext。
HandleSubscriber类同时扮演了Subscription、Subscriber、SynchronousSink三重角色。
@Override
public void onNext(T t) {
if (done) {
Operators.onNextDropped(t, actual.currentContext());
return;
}
try {
//在这里将小写字母转化为大写,内部调用了this.next(t)
handler.accept(t, this);
}
catch (Throwable e) {
Throwable e_ = Operators.onNextError(t, e, actual.currentContext(), s);
if (e_ != null) {
onError(e_);
}
else {
reset();
s.request(1);
}
return;
}
//this.next(t)中对data进行了赋值
R v = data;
data = null;
if (v != null) {
//如果v不为null,继续向下游传递
actual.onNext(v);
}
if(stop){
if(error != null){
Throwable e_ = Operators.onNextError(t, error, actual.currentContext(), s);
if (e_ != null) {
onError(e_);
}
else {
reset();
s.request(1L);
}
}
else {
s.cancel();
onComplete();
}
}
else if(v == null){
s.request(1L);
}
}
HandleSubscriber#next
@Override
public void next(R o) {
//在这里也解释了,为什么仅能在BiConsumer中执行一次sink.next操作
if(data != null){
throw new IllegalStateException("Cannot emit more than one data");
}
if (stop) {
throw new IllegalStateException("Cannot emit after a complete or error");
}
data = Objects.requireNonNull(o, "data");
}