Реактивный поиск с помощью RxJS Observable Vs Subject

Ниже приведены два подхода к одной и той же проблеме: выполнить реактивный поиск некоторых символов, которые пользователь вводит в текстовое поле. Первое решение взято из примера ngrx, а второе - из курса мгновенного поиска.

  • Первое решение использует Observable в то время как второй использует Subject,
  • Observable решение использует takeUntil позвонить на сервер только один раз. Subject решение использует distinctUntilChanged,

Может ли кто-нибудь объяснить преимущества и недостатки этих двух подходов?

Поиск с использованием Observable:

@Injectable()
export class BookEffects {

  @Effect()
  search$: Observable<Action> = this.actions$
    .ofType(book.ActionTypes.SEARCH)
    .debounceTime(300)
    .map(toPayload)
    .switchMap(query => {
      if (query === '') {
        return empty();
      }

      const nextSearch$ = this.actions$.ofType(book.ActionTypes.SEARCH).skip(1);

      return this.googleBooks.searchBooks(query)
        .takeUntil(nextSearch$)
        .map(books => new book.SearchCompleteAction(books))
        .catch(() => of(new book.SearchCompleteAction([])));
    });

    constructor(private actions$: Actions, private googleBooks: GoogleBooksService) { }
}

@Component({
  selector: 'bc-find-book-page',
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `
    <bc-book-search [query]="searchQuery$ | async" [searching]="loading$ | async" (search)="search($event)"></bc-book-search>
    <bc-book-preview-list [books]="books$ | async"></bc-book-preview-list>
  `
})
export class FindBookPageComponent {
  searchQuery$: Observable<string>;
  books$: Observable<Book[]>;
  loading$: Observable<boolean>;

  constructor(private store: Store<fromRoot.State>) {
    this.searchQuery$ = store.select(fromRoot.getSearchQuery).take(1);
    this.books$ = store.select(fromRoot.getSearchResults);
    this.loading$ = store.select(fromRoot.getSearchLoading);
  }

  search(query: string) {
    this.store.dispatch(new book.SearchAction(query));
  }
}

Поиск с использованием темы:

import { Component } from '@angular/core';
import { WikipediaSearchService } from './wikipedia-search.service';
import { Subject } from 'rxjs/Subject';

//application wide shared Rx operators
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/debounceTime';
import 'rxjs/add/operator/distinctUntilChanged';
import 'rxjs/add/operator/switchMap';

@Component({
  moduleId: module.id,
  selector: 'app-root',
  templateUrl: 'app.component.html',
  styleUrls: ['app.component.css']
})
export class AppComponent {
  items:Array<string>;
  term$ = new Subject<string>();
  constructor(private service:WikipediaSearchService) {

    this.term$
        .debounceTime(400)
        .distinctUntilChanged()
        .switchMap(term => this.service.search(term))
        .subscribe(results => this.items = results);
  }
}

<div>
  <h2>Wikipedia Search</h2>
  <input (input)="term$.next($event.target.value)">
  <ul>
    <li *ngFor="let item of items">{{item}}</li>
  </ul>
</div>

1 ответ

Поведение Субъект - это тип субъекта, субъект - это особый тип наблюдаемых, поэтому вы можете подписываться на сообщения, как и любые другие наблюдаемые. Уникальные особенности субъекта поведения:

  • Субъекту поведения необходимо начальное значение, так как он всегда должен возвращать значение в подписке, даже если он не получил next()
  • При подписке возвращается последнее значение предмета. Обычная наблюдаемая срабатывает только тогда, когда она получает следующий текст в любой момент, когда вы можете извлечь последнее значение субъекта в ненаблюдаемом коде, используя метод getValue().
  • Уникальные особенности предмета по сравнению с наблюдаемым:

Это наблюдатель в дополнение к тому, что он является наблюдаемым, поэтому вы также можете отправлять значения субъекту в дополнение к подписке на него. Кроме того, вы можете получить наблюдаемое от субъекта поведения, используя метод asobservable () для субъекта поведения.

Наблюдаемый является Обобщающим, и субъект Поведения технически является подтипом Наблюдаемого, потому что субъект поведения является наблюдаемым с определенными качествами.

Наблюдаемые могут быть созданы как из обычных, так и из поведенческих субъектов, используя subject.asobservable(). Разница лишь в том, что вы не можете отправлять значения наблюдаемой с помощью метода next().

В сервисах angular2 я бы использовал субъект поведения для сервиса данных, так как угловой сервис часто инициализируется до того, как компонент и субъект поведения гарантируют, что компонент, использующий сервис, получит последние обновленные данные, даже если нет новых обновлений с момента подписки компонента на эти данные., Короче говоря, многие вещи похожи в наблюдаемом / субъекте / поведении субъекта и т. Д., Это зависит от ваших потребностей.

Другие вопросы по тегам