原文:Debugging RxJS, Part 1: Toolinggit
譯者:Ice Panpan;校驗者:暫無github
我是一個 Rxjs
的信仰者,我在我全部的項目中都使用 Rxjs
。有了 Rxjs
,我發現不少曾經以爲乏味的事都變得痛快。可是有一件事不是這樣:調試。正則表達式
Rxjs
中異步的本質在組合以後讓調試變得更具挑戰性:沒有太多的狀態(state)供你檢查,而且調用堆棧(call stack)也幫不了太大的忙。我過去使用的方法是在整個代碼多處添加 do
操做符而且記錄,以此來檢查那些組合的 Observable
產生的值。這並非我想要的方法,由於:npm
log
操做符,結果也不會很理想。最近,我留了一些時間來爲 Rxjs
構建一個調試工具,我以爲這個工具必須具有如下的功能:瀏覽器
若是想要更完美,還要一些東西:異步
Observable
;Observable
或者它們發出的值;考慮到這些功能,我創建了 rxjs-spy
。函數
rxjs-spy
引入了 tag
操做符,將字符串標記與 Observable
相關聯。這個操做符不會以任何方式更改 Observable
的行爲或值。工具
tag
操做符能夠被單獨導入-js import "rxjs-spy/add/operator/tag"
-而且其餘的 rxjs-spy
方法能夠在生產環境下省略,因此惟一的開銷就是字符串註釋。spa
大多數工具的方法接受匹配器,以肯定它們將應用於哪些標記的 Observable
。匹配器能夠是傳遞標籤自己的簡單字符串,正則表達式或謂詞。prototype
經過調用 spy
來配置工具時,它會修改 Observable.prototype.subscribe
來監聽全部的 subscriptions
, notifications
和 unsubscriptions
。這也就是意味着,只有已經被訂閱的 Observable
纔會被監聽。
rxjs-spy
公開了一個旨在從代碼中調用的模塊API和一個用於在瀏覽器控制檯中交互使用的控制檯API。大多數時候,我早早地在應用程序啓動代碼裏條用模塊API的方法,並使用控制檯API進行剩餘的調試。
在調試時,我一般使用瀏覽器的控制檯來檢查和操做標記的 Observables
。控制檯API功能最容易經過示例解釋:
import { Observable } from "rxjs/Observable";
import { spy } from "rxjs-spy";
import "rxjs/add/observable/interval";
import "rxjs/add/operator/map";
import "rxjs/add/operator/mapTo";
import "rxjs-spy/add/operator/tag";
spy();
const interval = new Observable
.interval(2000)
.tag("interval");
const people = interval
.map((value) => {
const names = ["alice", "bob"];
return names[value % names.length];
})
.tag("people")
.subscribe();
複製代碼
rxjs-spy
中的控制檯API經過 rxSpy
在全局暴露。
調用 rxSpy.show()
將顯示全部已經被標記的 Observable
的列表,指示其狀態(incomplete
,complete
或者 errored
),訂閱者(subscribers
)的數量和最近發出的值(若是已經發出一個值)。控制檯輸出將以下所示:
要顯示特定標記的 Observable
的信息,能夠將標記名稱或者正則表達式傳遞給 show
:
能夠經過調用 rxSpy.log
來顯示被標記的 Observable
的日誌信息:
log
不帶參數調用將會顯示全部標記的 Observable
的日誌記錄。
模塊API中的大多數方法都返回一個撤銷功能,能夠調用該功能來撤銷方法調用。在控制檯中,管理起來很繁瑣,因此還有另外一種選擇。
調用 rxSpy.undo()
將顯示已經調用的方法的列表:
調用 rxSpy.undo
並傳遞與方法調用關聯的數字將看到該調用的撤銷函數被執行。例如,調用 rxSpy.undo(3)
將看到被標記爲 interval
的 Observable
的記錄被撤銷以後的結果:
有時,在調試時修改 Observable
或其值時,這個方法就頗有用。控制檯API包含一種 let
方法,其功能與 RxJS
中的 let
操做符大體相同。它的實現方式是經過調用 let
方法對標記的 Observable
的當前和將來的訂閱者產生影響。例如。如下調用將看到 people
Observable
發射 mallory
而不是 alice
或 bob
:
與 log
方法同樣,let
能夠撤消對該方法的調用:
可以在調試時暫停一個 Observable
對我來講幾乎是不可或缺的。調用 rxSpy.pause
將暫停一個標記的 Observable
,並返回一個可用於控制和檢查 Observable
的通知(notifications
)的 deck
:
在該 deck
上調用 log
將顯示 Observable
是否暫停,並顯示被暫停的通知(notifications
)。(通知是 Notification
使用 materialize
操做符得到的rxjs實例)
在 deck
上調用 step
將發出一個被暫停住的通知(notifications
):
調用 resume
將發出全部被暫停的通知(notifications
),並將恢復 Observable
:
調用 pause
將看到 Observable
從新進入暫停狀態:
很容易忘記將返回的 deck
分配給變量,所以控制檯API包含一個 deck
方法,和 undo
方法行爲類似。調用它將顯示 pause
調用的列表:
調用它並傳遞與調用相關聯的數字將返回相對應的 deck
:
像 log
和 let
的調用同樣,pause
的調用也能夠撤銷。撤銷 pause
的調用將看到標記的 Observable
恢復正常:
但願以上的例子能夠對 rxjs-spy
的控制檯API進行一個概述。Debugging RxJS
的後續部分將重點介紹 rxjs-spy
的具體功能以及如何使用它們來解決實際的調試問題。
對我來講,rxjs-spy
確定讓調試Rxjs再也不那麼繁瑣。
rxjs-spy
的代碼能夠在 GitHub上找到,而且有一個在線的控制檯API示例。
該包能夠經過NPM進行安裝。
有關本系列的一下篇文章,請參閱調試 Rxjs(二):日誌記錄