Как преобразовать свойства в RXJS Observable - PullRequest
2 голосов
/ 26 июня 2019

Мне нужно преобразовать свойство объекта в RXJS Observable.Это работает с использованием оператора «карта».Проблема возникает, когда я дважды подписываюсь на одну и ту же наблюдаемую информацию: свойство трансформируется дважды

Я пытался использовать оператор "share" и несколько вариантов, но, похоже, ничего не работает

Пример кода:

    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)
    );

Ожидаемый результат:

first:  John_test
second:  John_test

Фактический результат:

first:  John_test
second:  John_test_test

Ответы [ 2 ]

5 голосов
/ 26 июня 2019

Это потому, что вы модифицируете один и тот же экземпляр объекта дважды.Когда ваша карта вернет копию этого объекта, этого не произойдет.Попробуйте это:

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

Вы также можете использовать оператор shareReplay с вашей оригинальной функцией отображения:

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

Stackblitz

0 голосов
/ 26 июня 2019

Другое решение состоит в том, чтобы использовать Observable.create или new Observable() для создания наблюдаемой.

of создает многоадресную заметку. new Observable приведет к созданию холодной, одноадресной Наблюдаемой, которая испускает новый экземпляр вашего объекта для каждого Наблюдателя.

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)
);

Рабочий StackBlitz:

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

Я также недавно написал статью, объясняющую горячие и холодные наблюдаемые, которые могут оказаться полезными:

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

...