除錯 Rxjs(一):工具
原文: ofollow,noindex">Debugging RxJS, Part 1: Tooling
譯者: Ice Panpan ;校驗者:暫無

我是一個 Rxjs
的信仰者,我在我所有的專案中都使用 Rxjs
。有了 Rxjs
,我發現很多曾經覺得乏味的事都變得痛快。但是有一件事不是這樣:除錯。
Rxjs
中非同步的本質在組合之後讓除錯變得更具挑戰性:沒有太多的狀態(state)供你檢查,並且呼叫堆疊(call stack)也幫不了太大的忙。我過去使用的方法是在整個程式碼多處新增 do
操作符並且記錄,以此來檢查那些組合的 Observable
產生的值。這並不是我想要的方法,因為:
log
最近,我留了一些時間來為 Rxjs
構建一個除錯工具,我覺得這個工具必須具備以下的功能:
- 應該儘可能的不顯眼;
- 不需要通過修改程式碼來進行除錯;
- 在除錯結束後,不需要刪除或註釋掉除錯的程式碼;
- 應該可以輕鬆的啟用和禁用日誌記錄;
- 它應該提供與瀏覽器控制檯的一些整合————用於開啟/關閉除錯用能和檢查狀態等。
如果想要更完美,還要一些東西:
Observable Observable
考慮到這些功能,我建立了 rxjs-spy
。
核心概念
rxjs-spy
引入了 tag
操作符,將字串標記與 Observable
相關聯。這個操作符不會以任何方式更改 Observable
的行為或值。
tag
操作符可以被單獨匯入- js import "rxjs-spy/add/operator/tag"
-並且其他的 rxjs-spy
方法可以在生產環境下省略,所以唯一的開銷就是字串註釋。
大多數工具的方法接受匹配器,以確定它們將應用於哪些標記的 Observable
。匹配器可以是傳遞標籤本身的簡單字串,正則表示式或謂詞。
通過呼叫 spy
來配置工具時,它會修改 Observable.prototype.subscribe
來監聽所有的 subscriptions
, notifications
和 unsubscriptions
。這也就是意味著,只有已經被訂閱的 Observable
才會被監聽。
rxjs-spy
公開了一個旨在從程式碼中呼叫的模組API和一個用於在瀏覽器控制檯中互動使用的控制檯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不再那麼繁瑣。