我有 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/