Практические различия между явной подпиской на Observable и вызовом subscribe () с параметром - PullRequest
0 голосов
/ 17 февраля 2020

У меня есть служба, которая возвращает Observable:

contactsSerice (): Observable<Contact[]> {...}

Для использования этих данных в моем шаблоне и поддержания шаблона «живым» на основе того, что в Observable, я нашел два способа.

Я объявил Subject в контексте моего Компонента:

export class ExampleComponent implements OnInit {

    contacts$: Subject<Contact[]> = new Subject<Contact[]>();
    constructor(){}

}

А затем:

  1. Явно подписался на Observable (и выпустил контакты) как это:
ngOnInit() {

   this.contactsSerice().subscribe((contacts: Contact[]) => {
           this.contacts$.next(contacts);
   });
}
Прямой вызов .subscribe() с использованием моего субъекта в качестве параметра:
ngOnInit() {
  this.contactsSerice().subscribe(this.contacts$);
}

После этого я могу использовать | async канал в шаблоне, например:

<section *ngIf="contacts$ | async as contacts">
...
</section>

Мне было интересно, есть ли какая-либо практическая разница между вызовом subscribe(), передачей Субъекта и правильной подпиской на Наблюдаемое и инициированием метода Субъекта next().

Ответы [ 2 ]

1 голос
/ 17 февраля 2020

Существует фактическая разница:

Когда мы подписываемся через Subject, тогда error и complete уведомления передаются на него. Так что, если наш исходный объект наблюдения завершается, то тема также завершается. Это может быть нежелательным поведением, потому что завершенный Subject игнорирует все дальнейшие уведомления.

 /*
 Variant 1:
   This works only once:
     - The complete notification from the HTTP call is forwarded to the subscribing subject
     - A completed subject ignores further values
 */
 this.inventoryService.loadBeers(page).subscribe(this.beers$);


 // could be thought of the same as: 
 this.inventoryService.loadBeers()
   .subscribe(
     (response) => this.beers$.next(response), 
     (error) => this.beers$.error(error), 
     () => this.beers$.complete()
 );

 /*  
  Variant 2: Here we don't pass the completed event to the beers$ 
 */
 this.inventoryService.loadBeers()
   .subscribe(
     (response) => this.beers$.next(response), 
     (error) => console.log('Errors are not passed to beers$ subject'), 
     () => console.log('Complete notification is not passed to beers$ subject')
 );

Вы также можете взглянуть на пример stackblitz , где я пытался показать это поведение.

0 голосов
/ 17 февраля 2020

Коротких ответов нет, разницы нет (кроме того, что вы будете использовать немного больше памяти для самого предмета).

С практической точки зрения (скажем, вопрос в том, когда следует Я использую промежуточный предмет), вы хотите использовать промежуточные предметы всякий раз, когда вы хотите каким-либо образом кэшировать ответ, который вы получаете от своего сервера.

Скажем, например, что вы хотите сделать следующее

// Left side of the screen
<section *ngIf="contacts$ | async as contacts">
...
</section>

// Right side of the screen
<section *ngIf="contacts$ | async as contacts">
...
</section>

Таким образом, в этом случае, если вы используете сервис напрямую, вы сделаете два вызова на сервер (так как каждый |async является новой подпиской).

Итак, краткий ответ: разницы не будет, но лучше ее иметь.

** Примечание: если вы новичок в Angular и у вас проблемы с управлением состояниями , посмотрите в NGRX.

...