golang logrus 记录错误堆栈_调试 Rxjs(二):日志记录

0d7525d7125a3ba23778f317f6a2af3b.png

原文:

Debugging RxJS, Part 2: Logging​blog.angularindepth.com


译者:

TanYiBing - Overview​github.com
097c4391756984d167ac45f3b1517110.png

日志记录并不是一件让人兴奋的事。

然而,这是获得足够的信息来推理问题最直接的方法,而不需要去猜测。它通常是调试 RxJS 代码的首选方法。这是这个系列文章的第二篇,专注于使用日志记录来解决实际问题。在第一篇调试 Rxjs(一):工具中,主要介绍的是 rxjs-spy。在本文中,我将展示如何使用 rxjs-spy 以最小的影响来获取详细并有针对性的信息。

让我们看一个使用 rxjsrxjs-spy UMD捆绑的简单案例:

RxSpy.spy();
RxSpy.log(/user-.+/);
RxSpy.log('users');

const names = ['benlesh', 'kwonoj', 'staltz'];
const users = Rx.Observable.forkJoin(...names.map(name =>
  Rx.Observable
    .ajax
    .getJSON(`https://api.github.com/users/${name}`)
    .tag(`user-${name}`)
))
.tag('users');

users.subscribe();

该示例使用 forkJoin 组合了一个用来发射出GitHub用户数组的 Observable

rxjs-spy 使用 tag 操作符来标记 Observable,并且仅仅通过字符串来给 Observable 注释。这个示例在组合 Observable 之前,首先启用监听功能,并配置了哪些 Observable 要被记录——匹配 /user-.+/ 的正则表达式或者带有 users 标签的那些 Observable

这个示例的控制台输出如下:

013b4be62e4e867169be76861de5eeda.png

除了 Observablenextcomplete 的通知之外,记录的输出还包括订阅和取消订阅的通知。它显示了发生的一切:

  1. 对组合的 Observable 的订阅影响的每一个用户API请求的 Observable 的并行订阅;
  2. 请求以任意顺序完成;
  3. Observable 全部完成;
  4. 并且在全部完成后取消对组合 Observable 的订阅。

每个记录的通知还包括有关接受通知的订阅者的信息——包括订阅者具有的订阅量以及 subscribe 调用的堆栈痕迹:

28da463669be8c3499dee6ab5f3600d0.png

堆栈痕迹指的是 subscribe 调用的根——即影响订阅者对 Observable 订阅的显式调用。因此,用户请求的 Observable 的堆栈痕迹也参考了 medium.js 中的 subscribe 调用:

5c7267e14e6a55c36dee9410f69b48f0.png

当我调试时,我发现知道调用 subscribe 的实际的根位置比知道组合 Observable 中某个 subscribe 的位置更有用。

现在让我们看一个现实中实际的问题。

在编写 redux-observable epicsngrx effects 时,我看到几个开发人员类似的代码:

import { Observable } from 'rxjs/Observable';
import { ajax } from 'rxjs/observable/dom/ajax';

const getRepos = action$ =>
  action$.ofType('REPOS_REQUEST')
    .map(action => action.payload.user)
    .switchMap(user => ajax.getJSON(`https://api.notgithub.com/users/${user}/repos`))
    .map(repos => { type: 'REPOS_RESPONSE', payload: { repos } })
    .catch(error => Observable.of({ type: 'REPOS_ERROR' }))
    .tag('getRepos');

乍一看,这看上去还不错。大部分时间它都可以正常工作,它是那种可以偷偷混过单元测试的bug。

问题是,它有时会停止工作,特别是在一个错误的动作发生之后。

记录显示正在发生的事:

f76ba7b5f85d08428d8c01768f2c0851.png

在错误的动作被发射出去之后,看到 redux-observalbe基础结构从epic中解除订阅的 Observable 完成了。该文档的 catch 解释了为什么出现这种情况。

无论 selector 返回了什么样的 Observable,都将连在 Observable 链后面。

在这个epic中,catch 完成后返回的 Observable 也看到了epic的完成。

解决的方案是将 mapcatch 移到 switchMap 中,像下面这样:

import { Observable } from 'rxjs/Observable';
import { ajax } from 'rxjs/observable/dom/ajax';

const getRepos = action$ =>
  action$.ofType('REPOS_REQUEST')
    .map(action => action.payload.user)
    .switchMap(user => ajax
      .getJSON(`https://api.notgithub.com/users/${user}/repos`)
      .map(repos => { type: 'REPOS_RESPONSE', payload: { repos } })
      .catch(error => Observable.of({ type: 'REPOS_ERROR' }))
    )
    .tag('getRepos');

这个epic将不再完成,并继续发送错误动作:

6f0702543e06450feea25536b6582db0.png

在这两个示例中,需要对正在调试的代码进行的唯一修改是添加了一些标记注释。

注释的影响很小,一旦添加,我倾向于将它们留在代码中。标签运算符可以独立于诊断 rxjs-spy 使用——使用rxjs-spy/add/operator/tag 或直接导入 rxjs-spy/operator/tag,因此保留标记的开销很小。

可以使用正则表达式配置记录器,这可以产生许多可能的标记方法。例如,使用复合标记,例如 github/usersgithub/repos 将允许您为所有被标记后存储在存储库里的 github Observable 启用日志记录。

记录并不令人兴奋,但可以从记录的输出中收集的信息通常可以节省大量时间。采用灵活的标记方法可以进一步减少处理与日志记录相关的代码所花费的时间。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值