[翻譯] 調試 Rxjs(一):工具

原文:Debugging RxJS, Part 1: Toolinggit

譯者:Ice Panpan;校驗者:暫無github

我是一個 Rxjs 的信仰者,我在我全部的項目中都使用 Rxjs。有了 Rxjs,我發現不少曾經以爲乏味的事都變得痛快。可是有一件事不是這樣:調試。正則表達式

Rxjs 中異步的本質在組合以後讓調試變得更具挑戰性:沒有太多的狀態(state)供你檢查,而且調用堆棧(call stack)也幫不了太大的忙。我過去使用的方法是在整個代碼多處添加 do 操做符而且記錄,以此來檢查那些組合的 Observable 產生的值。這並非我想要的方法,由於:npm

  1. 當我在調試時修改代碼,我不得不進行更多的日誌記錄工做;
  2. 當調試結束以後,我必須刪除日誌記錄或者註釋掉它;
  3. 當在一個正常的組合Observable中存在‘拍扁’的操做時,如何進行日誌記錄須要格外的當心。
  4. 就算是專門有的 log 操做符,結果也不會很理想。

最近,我留了一些時間來爲 Rxjs 構建一個調試工具,我以爲這個工具必須具有如下的功能:瀏覽器

  1. 應該儘量的不顯眼;
  2. 不須要經過修改代碼來進行調試;
  3. 在調試結束後,不須要刪除或註釋掉調試的代碼;
  4. 應該能夠輕鬆的啓用和禁用日誌記錄;
  5. 它應該提供與瀏覽器控制檯的一些集成————用於打開/關閉調試用能和檢查狀態等。

若是想要更完美,還要一些東西:異步

  1. 它應該支持暫停 Observable
  2. 它應該支持修改 Observable 或者它們發出的值;
  3. 它應該支持控制檯意外的日誌記錄機制;
  4. 它應該是可擴展的;
  5. 它應該在某種程度上能夠捕獲可視化訂閱依賴關係所需的數據。

考慮到這些功能,我創建了 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, notificationsunsubscriptions。這也就是意味着,只有已經被訂閱的 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 的列表,指示其狀態(incompletecomplete 或者 errored),訂閱者(subscribers)的數量和最近發出的值(若是已經發出一個值)。控制檯輸出將以下所示:

要顯示特定標記的 Observable 的信息,能夠將標記名稱或者正則表達式傳遞給 show

能夠經過調用 rxSpy.log 來顯示被標記的 Observable 的日誌信息:

log 不帶參數調用將會顯示全部標記的 Observable 的日誌記錄。

模塊API中的大多數方法都返回一個撤銷功能,能夠調用該功能來撤銷方法調用。在控制檯中,管理起來很繁瑣,因此還有另外一種選擇。

調用 rxSpy.undo() 將顯示已經調用的方法的列表:

調用 rxSpy.undo 並傳遞與方法調用關聯的數字將看到該調用的撤銷函數被執行。例如,調用 rxSpy.undo(3) 將看到被標記爲 intervalObservable 的記錄被撤銷以後的結果:

有時,在調試時修改 Observable 或其值時,這個方法就頗有用。控制檯API包含一種 let 方法,其功能與 RxJS 中的 let 操做符大體相同。它的實現方式是經過調用 let 方法對標記的 Observable 的當前和將來的訂閱者產生影響。例如。如下調用將看到 people Observable 發射 mallory 而不是 alicebob:

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

loglet 的調用同樣,pause 的調用也能夠撤銷。撤銷 pause 的調用將看到標記的 Observable 恢復正常:

但願以上的例子能夠對 rxjs-spy 的控制檯API進行一個概述。Debugging RxJS 的後續部分將重點介紹 rxjs-spy 的具體功能以及如何使用它們來解決實際的調試問題。

對我來講,rxjs-spy 確定讓調試Rxjs再也不那麼繁瑣。

更多信息

rxjs-spy 的代碼能夠在 GitHub上找到,而且有一個在線的控制檯API示例

該包能夠經過NPM進行安裝。

有關本系列的一下篇文章,請參閱調試 Rxjs(二):日誌記錄

相關文章
相關標籤/搜索