我是一位 rxjs 信徒,在我所有活躍的專案中都在使用它。用了它之後,我發現很多乏味的事現在都變得很簡單。然而,有一件事卻沒有任何好轉,那就是除錯。
由於 rxjs 的可組合性與有時是非同步的本質使得除錯變成了一種挑戰:沒有太多的狀態可以觀察,而且呼叫堆疊基本也沒什麼幫助。我之前的做法是在整個**庫中穿插大量的do
操作符和日誌來檢查流經組合 observables 的值。由於以下幾點原因,我對這種方法並不滿意:
最近,我花費了一些時間開發了乙個 rxjs 的除錯工具。它有如下幾個功能,而且我覺得是這個工具必須要具備的:
還有一些功能,如果能有就更好了:
綜合考慮這些功能後,我開發了rxjs-spy
。
rxjs-spy
引入了tag
操作符,它將乙個字串標籤和乙個 observable 關聯起來。這個操作符並沒有以任何方式來改變 observable 的行為和值。
tag
操作符可以單獨使用:import "rxjs-spy/add/operator/tag"
。這樣的話,rxjs-spy
的其他方法會在生成版本中被忽略,所以唯一的開銷就是字串的使用 (匯入)。
大多數工具方法都接受匹配器 ( matchers ),以確定它們即將應用哪些標記過的 observables 。匹配器可以是簡單的字串、正規表示式或傳遞標籤本身的函式謂詞 ( predicates )。
當通過呼叫工具的spy
方法配置後,它會在observable.prototype.subscribe
上打補丁,這樣它就能夠偵察到所有的訂閱、通知和取消訂閱。當然,只有被訂閱的 observables 才能通過spy
進行偵察。
rxjs-spy
公開了乙個模組 api 用於在**中呼叫,還公開了乙個控制台 api 供使用者在瀏覽器的控制台中進行互動。大多數時候,我都是在應用的啟動**中早早地呼叫模組 api 的spy
方法,然後使用控制台 api 來執行剩下的除錯工作。
除錯時,我通常使用瀏覽器的控制台來檢查和操縱標記過的 observables 。控制台 api 還是通過示例來解釋比較容易,下面的**示例展示了如何與 observables 配合使用:
import from
"rxjs/observable";
import 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) => )
.tag("people")
.subscribe();複製**
rxjs-spy
的控制台 api 是通過全域性變數rxspy
公開的。
呼叫rxspy.show()
會顯示所有標記過的 observables 列表,並表明它們的狀態 (未完成、已完成或報錯)、訂閱者的數量以及最新發出的值 (如果有值發出的話)。控制台輸出是像這樣的:
要顯示某個特定的標記 observable,需要將標籤名或正規表示式傳給show
:
通過呼叫rxspy.log
可以啟用某個標記 observable 的日誌:
呼叫log
時不帶任何引數會啟用所有標記 observables 的日誌。
模組 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 通知的 deck 物件:
呼叫 deck 的log
方法會顯示 observable 是否暫停和暫停期間的所有通知 (通知是使用materialize
操作符獲取的 rxjs 的notification
例項)。
呼叫 deck 的setp
方法會發出一條通知:
呼叫resume
方法會發出所有暫停期間的通知並恢復 observable:
呼叫pause
會看到 observable 再次回到暫停狀態:
很容易會忘記將返回的 deck 賦值給了哪個變數,所以控制台 api 還提供了deck
方法,它的行為類似於undo
方法。呼叫它會顯示所有pause
呼叫的列表:
就像log
和let
呼叫一樣,pause
呼叫也可以取消,並且取消pause
呼叫會恢復標記的 observable:
希望上面的示例會讓你對rxjs-spy
以及它的控制台 api 有乙個大致的了解。「 除錯 rxjs 」系統的後續部分會專注於rxjs-spy
的具體功能,以及如何使用它來解決實際的除錯問題。
對於我而言,rxjs-spy
確實可以使除錯 rxjs 變得有趣起來。
還可以通過 npm 來安裝包。
Hibernate硬事實第1部分
hibernate是乙個廣泛使用的orm框架。許多組織在其專案中使用它來管理其資料訪問層。但是,許多使用hibernate的開發人員並不完全了解其功能的全部內容。這是第1 週後在hibernate中鐵的事實集中series.other職位包括 hibernate硬事實第1部分 本文 hibernat...
MySQL系列,第1部分 Mysql簡介
mysql是乙個關係型資料庫管理系統 由瑞典 mysql ab 公司開發,目前屬於 oracle 公司。mysql 最流行的關係型資料庫管理系統 在 web 應用方面 mysql 是最好的 rdbms relational database management system,關聯式資料庫管理系統 ...
第1部分 Spring Gradle 多模組專案
概述 布局 在這裡,我們將使用平面布局將應用程式目錄保留為根專案目錄 pic 1 的兄弟。平面布局的優點是我們可以為每個應用程式使用不同的git儲存庫。在您的根專案的settings.gradle檔案中,我們需要在子專案中使用includeflat。pic 1.directory structure...