【问题标题】:Difference between concat and merge in rxjs6rxjs 6中concat和merge的区别
【发布时间】:2018-12-25 21:41:25
【问题描述】:

我有 lessons$ observable,它由 initialLessons$ 和 searchLessons$ observables 组合而成。

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

【问题讨论】:

  • 这是因为 concat 仅在您的 observables 完成后才会发出......因为 FromEvent 在上述情况下永远不会完成它不会工作......即使它没有完成,merge 也会发出所有值
  • 展示createHttpObservable的代码
  • @JBNizet 我已将其添加到问题中
  • 你为什么不简单地使用 Angular HttpClient?它返回行为正确的可观察对象(即它们完成)。 angular.io/guide/http
  • 我想我会在接下来的任务中做什么:)

标签: angular rxjs rxjs6


【解决方案1】:

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

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

由于您已经拨打了.then(data =&gt; observer.next(data)),因此您还可以添加complete() 电话。

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

【讨论】:

    猜你喜欢
    • 2016-11-10
    • 1970-01-01
    • 2017-11-18
    • 1970-01-01
    • 2019-09-16
    • 1970-01-01
    • 1970-01-01
    • 2019-04-01
    相关资源
    最近更新 更多