[譯] 調試 RxJS 第1部分: 工具篇

原文連接: blog.angularindepth.com/debugging-r…
本文爲 RxJS 中文社區 翻譯文章,如需轉載,請註明出處,謝謝合做!
若是你也想和咱們一塊兒,翻譯更多優質的 RxJS 文章以奉獻給你們,請點擊【這裏】git

我是一位 RxJS 信徒,在我全部活躍的項目中都在使用它。用了它以後,我發現不少乏味的事如今都變得很簡單。然而,有一件事卻沒有任何好轉,那就是調試。github

因爲 RxJS 的可組合性與有時是異步的本質使得調試變成了一種挑戰:沒有太多的狀態能夠觀察,並且調用堆棧基本也沒什麼幫助。我以前的作法是在整個代碼庫中穿插大量的 do 操做符和日誌來檢查流經組合 observables 的值。因爲如下幾點緣由,我對這種方法並不滿意:正則表達式

  • 我老是在不斷地添加日誌,調試的同時還要更改代碼
  • 調試完成後,對於日誌,我要麼一條條的進行手動刪除,要麼選擇忍受
  • 匆忙之中將 do 操做符隨意放置在一個組合 observable 中間時,應該避免有條件的日誌輸出的太恐怖
  • 即便是專門的日誌操做符,其體驗也不理想

最近,我花費了一些時間開發了一個 RxJS 的調試工具。它有以下幾個功能,並且我以爲是這個工具必需要具有的:typescript

  • 它應該儘量地不唐突
  • 它應該不須要靠不斷修改代碼來進行調試
  • 特別是,它應該不須要解決問題後靠手動刪除或註釋掉調試代碼
  • 它應該支持能夠輕鬆啓用和禁用的日誌
  • 它應該支持捕獲能夠隨時間進行比較的快照
  • 它應該提供一些與瀏覽器控制檯的集成,用於打開/關閉調試功能和檢查狀態,等等

還有一些功能,若是能有就更好了:npm

  • 它應該支持暫停 observables
  • 它應該支持修改 observables 或 observables 發出的值
  • 它應該支持除控制檯以外的日誌機制
  • 它應該是可擴展的
  • 它應該採起一些方法來捕獲可視化訂閱依賴所需的數據

綜合考慮這些功能後,我開發了 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 進行偵察。post

rxjs-spy 公開了一個模塊 API 用於在代碼中調用,還公開了一個控制檯 API 供用戶在瀏覽器的控制檯中進行交互。大多數時候,我都是在應用的啓動代碼中早早地調用模塊 API 的 spy 方法,而後使用控制檯 API 來執行剩下的調試工做。

控制檯 API 功能

調試時,我一般使用瀏覽器的控制檯來檢查和操縱標記過的 observables 。控制檯 API 仍是經過示例來解釋比較容易,下面的代碼示例展現瞭如何與 observables 配合使用:

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() 會顯示全部標記過的 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,而不是 alicebob

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 調用的列表:

使用 pause 調用相關聯的數字來調用 deck 方法並會返回相關聯的 deck 對象:

就像 loglet 調用同樣,pause 調用也能夠取消,而且取消 pause 調用會恢復標記的 observable:

但願上面的示例會讓你對 rxjs-spy 以及它的控制檯 API 有一個大體的瞭解。「 調試 RxJS 」系統的後續部分會專一於 rxjs-spy 的具體功能,以及如何使用它來解決實際的調試問題。

對於我而言,rxjs-spy 確實可使調試 RxJS 變得有趣起來。

更多信息

rxjs-spy 的源碼託管在 GitHub 上,這裏有一個能夠操做控制檯 API 的在線示例

還能夠經過 NPM 來安裝包。

本系列的下篇文章 —「 調試 RxJS 第2部分:日誌篇

相關文章
相關標籤/搜索