angular - rxjs 6 中 concat 和 merge 的区别

标签 angular rxjs rxjs6

我有 lessons$ observable,它结合了 initialLessons$searchLessons$ observable。

initialLessons$ 在页面加载时发出以获取类(class)列表,并在用户输入搜索输入时发出 searchLessons$ 以获取过滤结果。

当我使用 concat 组合这些 observable 时,只有 initialLessons$ observable 发出并且它似乎没有订阅 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();
  });
};

最佳答案

concat 将仅在前一个 Observable 完成时订阅下一个源 Observable。

而这在您的代码中不会发生。由 createHttpObservable 创建的 Observable 永远不会完成。它只发出一个 next() 但没有 complete()。所以这就是为什么你正在经历你所描述的。 concat 从未订阅过 searchLessons$ 因为 initialLessons$ 从未完成。

因为你已经在调用 .then(data => observer.next(data)) 你也可以在那里添加 complete() 调用。

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

关于angular - rxjs 6 中 concat 和 merge 的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53921613/

相关文章:

html - 如何以 Angular 实现带有.xml扩展名的openfile?

javascript - RxJS 使用第一个流的输出运行第二个流

reactjs - 如何获得史诗中的先前状态

angular - 错误处理程序和 RxJS 6.2.2

rxjs - 当 observable 完成时,我应该如何发出单个值?

Angular 响应式(Reactive)表单自定义控件异步验证

javascript - 根据 JSON 响应中的对象在页面中显示两个不同的按钮

Angular 2 - 组件之间的双向通信

angular - 我不能再将 forkjoin 与 rxjs 5.5.2 一起使用

angular - 在 Typescript 中的映射内部分配 Observable 时出现未定义问题