简体   繁体   English

如何在RXJS Observable中转换属性

[英]How to transform properties in a RXJS Observable

I have to transform an object property in a RXJS Observable. 我必须在RXJS Observable中转换对象属性。 This works using the "map" operator. 使用“地图”运算符可以工作。 The problem occurs when I subscribe twice to the same observable: the property is transformed twice 当我两次订阅同一个可观察对象时,将发生问题:属性被两次转换

I have tried to use the "share" operator and multiple variations but nothing seems to work 我尝试使用“共享”运算符和多种变体,但似乎无济于事

Code Example: 代码示例:

    const source = of(
      { id: 1, name: 'John' },
    );

    const personObservable = source.pipe(
      map(person => { 
        person.name = person.name + '_test'; return person; 
      }),
    );

    personObservable.subscribe(
      person => console.log('first: ', person)
    );

    personObservable.subscribe(
      person => console.log('second: ', person)
    );

Expected result: 预期结果:

first:  John_test
second:  John_test

Actual result: 实际结果:

first:  John_test
second:  John_test_test

It is because you are modifying same object instance twice. 这是因为您要两次修改同一对象实例。 When your map would return a copy of that object it would not happen. 当地图返回该对象的副本时,将不会发生。 Try this: 尝试这个:

const personObservable = source.pipe(
      map(person => ({
          ...person,
          name: person.name + '_test'
      })),
    );

You could also use shareReplay operator with your original mapping function: 您还可以将shareReplay运算符与原始映射功能一起使用:

const personObservable = source.pipe(
  map(person => { 
        person.name = person.name + '_test'; return person; 
      }),
  shareReplay()
);

Stackblitz Stackblitz

Another solution is to use Observable.create or new Observable() to create your Observable. 另一个解决方案是使用Observable.createnew Observable()创建您的Observable。

of creates a multicast Observable. of建立组播观察到。 new Observable will result in the creation of a cold, unicast Observable, which emits a new instance of your object for each Observer. new Observable将创建一个冷的单播Observable,它为每个Observer发出一个新的对象实例。

const source = new Observable((subscriber) => {
  subscriber.next({ id: 1, name: 'John' });
  subscriber.complete();
});

const personObservable = source.pipe(
  map(person => { 
    person.name = person.name + '_test'; return person; 
  }),
);

personObservable.subscribe(
  person => console.log('first: ', person)
);

personObservable.subscribe(
  person => console.log('second: ', person)
);

Working StackBlitz: 工作StackBlitz:

https://stackblitz.com/edit/angular-bdhjuo https://stackblitz.com/edit/angular-bdhjuo

I also recently wrote an article explaining hot and cold Observables, which you may find useful: 我最近还写了一篇文章,解释了热和冷的Observables,您可能会发现它很有用:

http://willtaylor.blog/rxjs-observables-hot-cold-explained/ http://willtaylor.blog/rxjs-observables-hot-cold-explained/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM