原文连接: blog.angularindepth.com/debugging-r…
本文为 RxJS 中文社区 翻译文章,如需转载,请注明出处,谢谢合做!
若是你也想和咱们一块儿,翻译更多优质的 RxJS 文章以奉献给你们,请点击【这里】git
我是一位 RxJS 信徒,在我全部活跃的项目中都在使用它。用了它以后,我发现不少乏味的事如今都变得很简单。然而,有一件事却没有任何好转,那就是调试。github
因为 RxJS 的可组合性与有时是异步的本质使得调试变成了一种挑战:没有太多的状态能够观察,并且调用堆栈基本也没什么帮助。我以前的作法是在整个代码库中穿插大量的 do
操做符和日志来检查流经组合 observables 的值。因为如下几点缘由,我对这种方法并不满意:正则表达式
do
操做符随意放置在一个组合 observable 中间时,应该避免有条件的日志输出的太恐怖最近,我花费了一些时间开发了一个 RxJS 的调试工具。它有以下几个功能,并且我以为是这个工具必需要具有的:typescript
还有一些功能,若是能有就更好了:npm
综合考虑这些功能后,我开发了 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 来执行剩下的调试工做。
调试时,我一般使用浏览器的控制台来检查和操纵标记过的 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
,而不是 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
调用的列表:
使用 pause
调用相关联的数字来调用 deck
方法并会返回相关联的 deck 对象:
就像 log
和 let
调用同样,pause
调用也能够取消,而且取消 pause
调用会恢复标记的 observable:
但愿上面的示例会让你对 rxjs-spy
以及它的控制台 API 有一个大体的了解。「 调试 RxJS 」系统的后续部分会专一于 rxjs-spy
的具体功能,以及如何使用它来解决实际的调试问题。
对于我而言,rxjs-spy
确实可使调试 RxJS 变得有趣起来。
rxjs-spy
的源码托管在 GitHub 上,这里有一个能够操做控制台 API 的在线示例。
还能够经过 NPM 来安装包。
本系列的下篇文章 —「 调试 RxJS 第2部分:日志篇 」