在类中使用 RxJs 主题时 JSON.stringify 上的循环对象异常

Posted

技术标签:

【中文标题】在类中使用 RxJs 主题时 JSON.stringify 上的循环对象异常【英文标题】:Cyclic Object Exception on JSON.stringify when with RxJs Subject in a class 【发布时间】:2018-09-01 10:21:25 【问题描述】:

我在使用序列化恰好具有 Rxjs 主题的类时遇到循环对象异常错误。如果我在课堂上订阅该主题,当我尝试字符串化时,我会得到一个循环对象异常。我的示例类这个...

export class ThingToStringIfy

  private someProp : string;
  private aSubject = new Subject();

   constructor() 
     this.aSubject.subscribe();

所以我的问题是我是否以某种方式错误地使用了该主题,或者我是否碰巧发现了一个错误。我目前正计划使用 JSON 替换函数或类似 circle-json-es6 的东西。任何有关解决方法或改进的建议将不胜感激。如果它是一个错误,我想成为一个好公民并实际报告它。

谢谢

这里是违规代码的链接: https://stackblitz.com/edit/angular-cpfsuu?embed=1&file=app/hello.component.ts

【问题讨论】:

你要字符串化什么?你为什么要把它串起来? 这里有一篇类似的文章考虑了 observables 的序列化:***.com/questions/34794995/… 【参考方案1】:

一般来说,observables 和 private 成员都不应该被序列化。这会导致序列化对象被不应该存在的属性污染。

一种方法是在 JS 输出中隐藏(不可枚举)私有 TypeScript 属性。这可以通过装饰器来实现:

function Private() 
  return function (target: any, prop: string, descriptor?: PropertyDescriptor) 
    if (descriptor) 
      // method
      descriptor.enumerable = false;
     else 
      // property initializer
      let propSymbol = Symbol(prop);

      Object.defineProperty(target, prop, 
        configurable: true,
        enumerable: false,
        get()  return this[propSymbol] ,
        set(value)  this[propSymbol] = value 
      );
    
  ;


export class ThingToStringIfy 
  @Private() private someProp : string;
  @Private() private aSubject = new Subject();
  ...

装饰器将private 属性排除在JSON.stringify 和其他只需要拥有可枚举属性的地方。

另一种方法是实现toJSON method 将被JSON.stringify 使用而不是默认例程:

export class ThingToStringIfy 
  private someProp : string;
  private aSubject = new Subject();
  ...
  toJSON() 
    const publicThis = Object.assign(, this);
    // or lodash.omit or any alternative
    delete publicThis['someProp'];
    delete publicThis['aSubject'];
    return publicThis;
  

【讨论】:

非常好.. 我唯一需要更改的是在 Private 前面添加 @ 是的,这是一个错字。很高兴它有帮助。

以上是关于在类中使用 RxJs 主题时 JSON.stringify 上的循环对象异常的主要内容,如果未能解决你的问题,请参考以下文章

Java-在类中找不到主要方法

Apollo GraphQL - 如何将 RxJS 主题用作 Apollo 客户端的变量?

为什么RxJS主题比多个事件监听器更快?

RxJS:取消订阅嵌套订阅

如何解决 TypeScript 2.4 和 RxJS 5.x 中的“主题不正确地扩展 Observable”错误?

角度服务中的 EventEmitter 或 RxJS 主题