原文:Debugging RxJS, Part 1: Toolinggit
译者:Ice Panpan;校验者:暂无github
我是一个 Rxjs
的信仰者,我在我全部的项目中都使用 Rxjs
。有了 Rxjs
,我发现不少曾经以为乏味的事都变得痛快。可是有一件事不是这样:调试。正则表达式
Rxjs
中异步的本质在组合以后让调试变得更具挑战性:没有太多的状态(state)供你检查,而且调用堆栈(call stack)也帮不了太大的忙。我过去使用的方法是在整个代码多处添加 do
操做符而且记录,以此来检查那些组合的 Observable
产生的值。这并非我想要的方法,由于:npm
log
操做符,结果也不会很理想。最近,我留了一些时间来为 Rxjs
构建一个调试工具,我以为这个工具必须具有如下的功能:浏览器
若是想要更完美,还要一些东西:异步
Observable
;Observable
或者它们发出的值;考虑到这些功能,我创建了 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
, notifications
和 unsubscriptions
。这也就是意味着,只有已经被订阅的 Observable
才会被监听。
rxjs-spy
公开了一个旨在从代码中调用的模块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再也不那么繁琐。
rxjs-spy
的代码能够在 GitHub上找到,而且有一个在线的控制台API示例。
该包能够经过NPM进行安装。
有关本系列的一下篇文章,请参阅调试 Rxjs(二):日志记录