RxJs fromEvent 工作原理分析
this.test 的賦值邏輯:
this.test = this.document.getElementById('test');每當(dāng)該 id 為 test 的按鈕被點(diǎn)擊一次,則 fromEvent issue 一個(gè)新的值,內(nèi)容為 MouseClick 事件:
本文介紹這個(gè)神奇的 fromEvent 的工作原理。
在 rxjs/_esm2015/index.js 下能看到所有 rxjs 支持的 operators:
fromEvent 構(gòu)造函數(shù)支持最多 4 個(gè)輸入?yún)?shù),但我的例子里,之傳入了兩個(gè)。因此直接進(jìn)入 Observable 對(duì)象的構(gòu)造邏輯:
Observable 的構(gòu)造函數(shù),只有一個(gè)輸入?yún)?shù),該輸入?yún)?shù)為一個(gè)函數(shù)。這個(gè)函數(shù)是一個(gè)匿名函數(shù),只有函數(shù)體而無(wú)函數(shù)名稱(chēng)。
把該匿名函數(shù)維護(hù)在 Observable 的私有屬性 _subscribe 里。
fromEvent 返回一個(gè)可觀察對(duì)象,調(diào)用該對(duì)象的 subscribe 方法,給其注冊(cè)觀察者。
上圖 observerOrNext 就是我們應(yīng)用程序里,傳入給 subscribe 方法的匿名函數(shù),即使用 console.log 打印 id 為 test 的 button 被點(diǎn)擊之后拋出的 MouseEvent 事件。
因?yàn)槲覀儠簳r(shí)沒(méi)有給 fromEvent 返回的 Observable 對(duì)象指定 operator,因此第 20 行 operator 為 undefined:
調(diào)用函數(shù) toSubscriber 創(chuàng)建一個(gè)新的 subscriber:
上圖 nextOrObserver 就是我應(yīng)用程序里指定的 console.log(event) 匿名函數(shù),只是用 Subscriber 包了一層。
Subscriber.js 內(nèi)部:Subscriber 的 destination 屬性,指向了 SafeSubscriber 實(shí)例:
再回到 Observable 的 subscribe 方法。現(xiàn)在我們知道了,在其 toSubscriber 方法里,創(chuàng)建了一個(gè) Subscriber 實(shí)例,其重要屬性如上圖1,2,3所示。因?yàn)闆](méi)有為該 Observable 指定 operator,所以第 22 行的 IF 分支進(jìn)不去,而是執(zhí)行第 26 行的 else 分支。
進(jìn)入 trySubscribe 方法:
_trySubscribe 是 _subscribe 方法的包裹,再加上錯(cuò)誤處理:
文章開(kāi)頭提到的 Observable 私有屬性 _subscribe, 指向 fromEvent.js 第14行匿名函數(shù):
現(xiàn)在執(zhí)行該匿名函數(shù),函數(shù)體內(nèi) setupSubscription.
如何判斷傳進(jìn)來(lái)的變量是 EventTarget 呢?
檢查其是否具有 addEventListner 和 removeEventListener 即可。
這里把 fromEvent.js 里某個(gè) handler 函數(shù),作為按鈕點(diǎn)擊后的事件處理函數(shù)進(jìn)行注冊(cè)。
注意,這里給 click 點(diǎn)擊事件注冊(cè)的,并不是我們應(yīng)用程序指定的 console.log(event), 而是 fromEvent.js 里一個(gè)內(nèi)部函數(shù),如下圖所示:
當(dāng)我點(diǎn)擊 UI 的 test 按鈕后,觸發(fā) click 事件,fromEvent.js 里定義的事件處理函數(shù)被調(diào)用:
還記得我們之前提到的 toSubscriber 函數(shù)調(diào)用么?將應(yīng)用程序定義的 console.log(event), 包裝成 SafeSubscriber,存儲(chǔ)到 _next 屬性里。
這里,最終觸發(fā) subscriber 的私有屬性 _next 指向的應(yīng)用程序處理邏輯:
使用了 JavaScript function 原生的 call 方法進(jìn)行調(diào)用:
最終,進(jìn)入了應(yīng)用程序打印代碼執(zhí)行,謎底就此解開(kāi):
更多Jerry的原創(chuàng)文章,盡在:“汪子熙”:
總結(jié)
以上是生活随笔為你收集整理的RxJs fromEvent 工作原理分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: SAP Spartacus Refere
- 下一篇: RxJs map operator 工作