rxjs基础
创建一个用于处理网络请求的observable
import { noop, Observable } from "rxjs";
// 创建一个可以用于fetch指定数据的observable
const http$ = new Observable((observer) => {
fetch("/api/courses")
.then((response) => response.json())
.then((body) => {
// 由于是冷的observable 只能next一次 同时complete应该发生在next之后
observer.next(body);
observer.complete();
})
.catch((err) => {
observer.error(err);
});
});
http$.subscribe(
(data) => {
console.log({ data });
},
noop,
() => {
console.log("complete");
}
);
rxjs算子
几种不同的map
this.form.valueChanges
.pipe(
filter(() => this.form.valid),
distinctUntilChanged(),
// concatMap在一个请求结束后执行下一个 瀑布流为顺序邻接
// concatMap((changes) => this.saveCourse(changes))
// 不会等上一个结束 瀑布流会有交叉
mergeMap((changes) => this.saveCourse(changes))
)
.subscribe((res) => {});
fromEvent(this.saveButton.nativeElement, "click")
// 当当前请求结束时 才会允许触发下一次请求 有点类似于throttle 用于防止按钮多次被按
.pipe(exhaustMap((changes) => this.saveCourse(this.form.value)))
.subscribe();
concatMap
concatMap
可以用于进行Observable的顺序连接,当一个ob发射结束后另一个ob发射,
它的事件瀑布流时顺序的,当一个时间执行结束后可以执行下一个事件。
可以想象到的一个使用场景是,定义一个初始化和初始化后继续执行的代码的同一性场景:
mergeMap
switchMap
exhaustMap
当前请求结束后才可以触发下一次请求
使用场景,按钮在点击后再次点击无效
shareReplay
将一个Ob置为热的,使它只会触发一次,见下面代码:
ngOnInit() {
// 创建一个可以用于fetch指定数据的observable
const http$: Observable<CoursePayload> = createHttpObservable(
"/api/courses"
) as Observable<CoursePayload>;
const courses$ = http$.pipe(
map((res) => Object.values(res.payload)),
// 变流为多播 只会触发一次
shareReplay()
);
this.beginnerCourse$ = courses$.pipe(
map((courses) => {
return courses.filter((course) => course.category === "BEGINNER");
})
);
this.advancedCourse$ = courses$.pipe(
map((courses) => {
return courses.filter((course) => course.category === "ADVANCED");
})
);
}
如果没有shareReplay,http请求会触发两次。