我們?cè)陂_發(fā)復(fù)雜的 Angular 應(yīng)用時(shí),經(jīng)常會(huì)使用到 Rxjs 的 defer 函數(shù),例如:

創(chuàng)建一個(gè) Observable,在訂閱時(shí)調(diào)用 Observable 工廠為每個(gè)新的 Observer 創(chuàng)建一個(gè) Observable 對(duì)象。

該函數(shù)接收一個(gè)輸入?yún)?shù),類型為一個(gè)工廠函數(shù)。輸出為一個(gè) Observable 對(duì)象,一旦被訂閱時(shí),其綁定的工廠函數(shù)會(huì)被調(diào)用。

defer 的實(shí)質(zhì)是延遲創(chuàng)建機(jī)制,即只有在返回的 Observable被訂閱時(shí),才開始創(chuàng)建 Observable 對(duì)象。

defer 允許你只在 Observer 訂閱時(shí)創(chuàng)建一個(gè) Observable。 它一直等到 Observer 訂閱它,調(diào)用給定的工廠函數(shù)來獲取一個(gè) Observable —— 工廠函數(shù)通常會(huì)生成一個(gè)新的 Observable —— 并將 Observer 訂閱到這個(gè) Observable。 如果工廠函數(shù)返回一個(gè)假值,則使用 EMPTY 作為 Observable 代替。 最后但并非最不重要的是,工廠函數(shù)調(diào)用期間的異常通過調(diào)用 error 傳遞給觀察者。

看下面這個(gè)具體的例子。

我們來單步調(diào)試下上面這段代碼。首先進(jìn)入 defer 內(nèi)部執(zhí)行邏輯:

在 defer 內(nèi)部,直接構(gòu)造一個(gè)新的 Observable,并且將工廠函數(shù)傳入。該工廠函數(shù)在第8行被調(diào)用,用于生成一個(gè)包含應(yīng)用程序業(yè)務(wù)邏輯的 Observable 對(duì)象,存儲(chǔ)在 input 里。最后,將應(yīng)用程序的subscriber 訂閱到這個(gè)工廠函數(shù)返回的 Observable 上。

我們?cè)賳尾綀?zhí)行,發(fā)現(xiàn)程序執(zhí)行流從上圖的第5行,跳轉(zhuǎn)到了 第16行。這體現(xiàn)了 defer 函數(shù)延遲創(chuàng)建 Observable 對(duì)象的行為。所謂延遲創(chuàng)建,準(zhǔn)確的說,應(yīng)該是延遲了包含業(yè)務(wù)邏輯的 Observable 對(duì)象的創(chuàng)建。

緊接著,回到我們的應(yīng)用代碼,此時(shí)針對(duì) defer 函數(shù)返回的 wrapper Observable 對(duì)象調(diào)用 subscribe,這時(shí)候就會(huì)觸發(fā)包含業(yè)務(wù)邏輯的 Observable 對(duì)象的創(chuàng)建了:

defer 返回的 wrapper Observable 的訂閱函數(shù)在此處執(zhí)行:

調(diào)用工廠方法,進(jìn)行包含業(yè)務(wù)邏輯的 Observable 對(duì)象創(chuàng)建:

當(dāng)前隨機(jī)數(shù)執(zhí)行結(jié)果大于 0.5,返回 fromEvent 生成的新 Observable 對(duì)象。

緊接著,第24行的匿名函數(shù) x => console.log(x),每當(dāng)屏幕被鼠標(biāo)點(diǎn)擊時(shí),就會(huì)觸發(fā)。這個(gè)匿名函數(shù)本來是訂閱到 defer 函數(shù)返回的 wrapper Observable 對(duì)象的。當(dāng)工廠函數(shù)返回了新的 Observable 對(duì)象后,它被自動(dòng)訂閱到這個(gè)新的 Observable 對(duì)象上。

總結(jié) defer 的工作原理:

(1) defer 函數(shù)被調(diào)用時(shí),傳入一個(gè)工廠函數(shù)作為輸入?yún)?shù)。這個(gè)工廠函數(shù)返回一個(gè)新的包含了業(yè)務(wù)邏輯的 Observable 對(duì)象。

(2) defer 函數(shù)返回另一個(gè)新的 Observable 對(duì)象,這個(gè) Observable 對(duì)象稱為 wrapper 或者 dummy Observable 對(duì)象,因?yàn)樗话魏螛I(yè)務(wù)邏輯,存活的唯一價(jià)值就是,實(shí)現(xiàn)業(yè)務(wù)邏輯 Observable 對(duì)象的延遲創(chuàng)建。

(3) 當(dāng) wrapper Observable 被訂閱時(shí),觸發(fā)工廠函數(shù)的執(zhí)行,生成新的 Observable 對(duì)象,同時(shí)通知其 Observer.

更多Jerry的原創(chuàng)文章,盡在:"汪子熙":