前言
通常來說在響應(yīng)式編程中 Publisher 的創(chuàng)建到真正的訂閱者中間會經(jīng)過許多的響應(yīng)式操作符,而大部分的操作符其實都是 OptimizableOperator 的實現(xiàn)驾霜。
隨便舉幾個例子案训,例如:map,flatMap粪糙,filter强霎,doOnNext 等等∪馗裕基本上所有對上游數(shù)據(jù)做處理的函數(shù)都實現(xiàn)了 OptimizableOperator
準(zhǔn)備工作
你需要對 Reactor 或者響應(yīng)式編程有一定了解
推薦閱讀:
「響應(yīng)式編程入門之 Project Reactor」
OptimizableOperator
首先 OptimizableOperator 繼承了 CorePublisher城舞,這沒什么可說的轩触,因為不管是使用 Mono 還是 Flux 執(zhí)行完任何操作之后返回的依舊是一個 Publisher
下面我們來看下 OptimizableOperator 的核心方法,先來簡單說下椿争,后邊會結(jié)合源碼來詳細(xì)理解
OptimizableOperator.subscribeOrReturn
該方法有兩種方式實現(xiàn)
- 返回一個 CoreSubscriber,返回的訂閱者包裝了下游的實際訂閱者
- 返回 null
當(dāng)選擇這種實現(xiàn)方式時熟嫩,當(dāng)前 OptimizableOperator 自行消費真正的 Publisher秦踪。將自己作為下游 Subscriber 的發(fā)布者
這兩種實現(xiàn)方式有什么區(qū)別呢?第一種方式僅僅是作為一個消費者訂閱掸茅。而第二種方式椅邓,Operator 相當(dāng)于翻身農(nóng)奴把歌唱了,自己當(dāng)上了 Publisher昧狮,能做的事情比一種方式更多
OptimizableOperator.source
返回當(dāng)前 OptimizableOperator 的上游(上游可能還是一個 OptimizableOperator)
OptimizableOperator.nextOptimizableSource
返回鏈中的下一個 OptimizableOperator(如果上游是 OptimizableOperator 則返回景馁,否則返回 null)
InternalMonoOperator
我們來通過 InternalMonoOperator 來理解一下上述的幾個方法
InternalMonoOperator 構(gòu)造方法
InternalMonoOperator 是所有 Mono 操作符的父類,在執(zhí)行操作符動作之前都會先構(gòu)建操作符對象逗鸣,最終會調(diào)用到 InternalMonoOperator 構(gòu)造方法合住。
- 入?yún)?source 為當(dāng)前操作符的上游,
- super(source) 內(nèi)部實現(xiàn)是將上游賦值給成員變量
source
- 如果上游同樣也是操作符撒璧,還會將其賦值給
optimizableOperator
subscribe
當(dāng)最后一個操作符被訂閱時會執(zhí)行如下邏輯透葛。看似很難讀卿樱,其實和上面我們講的是一樣的僚害,下面一起來分析下
public final void subscribe(CoreSubscriber<? super O> subscriber) {
// 將當(dāng)前對象賦值給 operator
OptimizableOperator operator = this;
try {
while (true) {
// 調(diào)用操作符的 subscribeOrReturn
// 1. 返回 != null,我們認(rèn)為 operator 已經(jīng)對實際訂閱者做了包裝繁调。所以繼續(xù)調(diào)用下一個操作符(也就是當(dāng)前操作符的上游)
// 2. 如果返回 == null萨蚕,則代表 operator 要自己處理上游的消費和下游的訂閱,方法結(jié)束
subscriber = operator.subscribeOrReturn(subscriber);
if (subscriber == null) {
// null means "I will subscribe myself", returning...
return;
}
// 返回當(dāng)前 operator 的下一個操作符(也就是返回的上游的操作符)
OptimizableOperator newSource = operator.nextOptimizableSource();
if (newSource == null) {
// 如果所有 operator 都執(zhí)行完了蹄胰,那么可以直接向 Publisher 發(fā)起訂閱了
// 訂閱結(jié)束后岳遥,退出當(dāng)前方法
operator.source().subscribe(subscriber);
return;
}
// 存在下一個操作符,繼續(xù)執(zhí)行該邏輯
operator = newSource;
}
}
catch (Throwable e) {
Operators.reportThrowInSubscribe(subscriber, e);
return;
}
}
在理解了 subscribe
的邏輯之后裕寨,我們在以后在閱讀 Reactor 操作符的源碼時寒随,就可以清楚地知道只需要關(guān)注該操作符的 subscribeOrReturn
方法即可。
如果 subscribeOrReturn
僅是返回一個 subscriber帮坚,那么我們只需要關(guān)注其 Subscriber 的相關(guān)邏輯即可妻往。如果返回的 null,則代表該操作符要自行消費上游然后向下游傳遞訂閱试和,我們需要關(guān)注他的 Subscription 相關(guān)
最后
如果覺得我的文章對你有幫助讯泣,動動小手點下關(guān)注,你的支持是對我最大的幫助