Разница между concat и merge в rxjs6 - PullRequest
0 голосов
/ 25 декабря 2018

У меня есть lessons$ наблюдаемый, который комбинируется из initialLessons$ и searchLessons$ наблюдаемых.

initialLessons$ генерирует загрузку страницы, чтобы получить список уроков, и когда пользователь вводитвходные данные поиска searchLessons$ испускают для получения отфильтрованных результатов.

Когда я использовал concat для объединения этих наблюдаемых, испускаются только наблюдаемые initialLessons$, и кажется, что он не подписан на searchLessons$совсем.Я заменил его на merge, и он работал нормально

Мне просто нужно знать, каково объяснение этого случая!

export class CourseComponent implements OnInit, AfterViewInit {
  @ViewChild('searchInput') input: ElementRef;

  courseId: string = this.route.snapshot.params['id'];

  course$: Observable<Course>;

  lessons$: Observable<Lesson[]>;

  constructor(private route: ActivatedRoute) {}

  ngOnInit() {
    this.course$ = createHttpObservable(`/api/courses/${this.courseId}`);
  }

  ngAfterViewInit() {
    const initialLessons$: Observable<Lesson[]> = this.loadLessons();

    const searchLessons$: Observable<Lesson[]> = fromEvent<any>(
      this.input.nativeElement,
      'keyup'
    ).pipe(
      debounceTime(400),
      map(event => event.target.value),
      distinctUntilChanged(),
      switchMap(search => this.loadLessons(search))
    );

    this.lessons$ = merge(initialLessons$, searchLessons$);
  }

  loadLessons(search = ''): Observable<Lesson[]> {
    return createHttpObservable(`/api/lessons?courseId=${this.courseId}&pageSize=100&filter=${search}`
).pipe(map(res => res['payload']));

}}

Редактировать:

Это createHttpObservable код:

import { Observable } from 'rxjs';

export const createHttpObservable = (url: string) => {
  return Observable.create(observer => {
    const controller = new AbortController();
    const signal = controller.signal;

    fetch(url, { signal })
      .then(res => res.json())
      .then(data => observer.next(data))
      .catch(err => console.error(err));

    return () => controller.abort();
  });
};

1 Ответ

0 голосов
/ 25 декабря 2018

concat подпишется только на следующий источник Observable, когда завершится предыдущий Observable.

И это то, что не происходит в вашем коде.Наблюдаемая, созданная createHttpObservable, никогда не завершается.Он излучает только один next(), но не complete().Вот почему вы испытывали то, что описали.concat никогда не подписывался на searchLessons$, потому что initialLessons$ никогда не завершался.

Поскольку вы уже звоните .then(data => observer.next(data)), вы можете добавить туда также complete() call.

.then(data => {
  observer.next(data);
  observer.complete();
})
...