我试图创建一种方法,在解析某个流时以普通方式显示和隐藏加载屏幕。
这是我当前的代码:
this.requestService
.get<Checkout>(`check/${orderNumber}`)
.pipe(
tap(() => this.startLoading()), //i think this isnt the right way to use this pipe
finalize(() => this.endLoading())
)
.subscribe(
data => {
data.orderNumber = orderNumber
this.checkout.next(data)
},
error => {
this.notification.warning(error)
}
)
预期的结果是,当我的流开始时,当操作完成时,显示带有startLoading()
的加载屏幕结束,使用endLoading()
隐藏加载。
我的工作代码:
this.startLoading() //basically calling function before i create the stream
this.requestService
.get<Checkout>(`check/${orderNumber}`)
.pipe(
finalize(() => this.endLoading())
)
.subscribe(
data => {
data.orderNumber = orderNumber
this.checkout.next(data)
},
error => {
this.notification.warning(error)
}
)
我是否正确使用此tap
管道?还有其他管道可以更好地解决这个问题吗?
使用RxJS最好的方法是什么?
在第一个示例中,您的tap在http请求完成后运行。
最终,您只需要在启动http请求之前调用this.startLoading()
。
this.startLoading();
this.requestService.get<Checkout>(`check/${orderNumber}`).pipe(
finalize(() => this.endLoading())
).subscribe(() => {
});
如果您真的想在管道中调用this.startLoading()
,您可以在http请求开始之前调用它,方法是从您自己的observable开始:
return of(null).pipe(
tap(() => this.startLoading()),
concatMap(() => this.requestService.get<Checkout>(`check/${orderNumber}`)),
finalize(() => this.endLoading())
).subscribe(() => {
});
但这样做并没有多大意义。
所以你的tap
语法是正确的,只是它没有在你认为应该执行的时候执行
如果您想对每个可观察的订阅执行副作用,可以使用defer()
扭曲源。
import { defer } from 'rxjs';
...
defer(() => {
this.startLoading();
return this.requestService.get<Checkout>(`check/${orderNumber}`);
}).pipe(
finalize(() => this.endLoading())
)
.subscribe(...);
您可以将BehaviorSubject
和RxJs defer
与finalize
管道一起使用,以跟踪加载过程。
import { defer } from 'rxjs';
// ...
public this.loading: BehaviorSubject<boolean> = new BehaviorSubject(false);
// ...
public getOrder(orderNumber): Observable<Checkout> {
defer(() => {
this.loading.next(true);
return this.requestService.get<Checkout>(`check/${orderNumber}`);
}).pipe(
finalize(() => this.loading.next(false)
);
}
// to get boolean from BehaviorSubject -> is loading
public isLoading(): boolean {
return this.loading.value;
}
// ...
现在,您还可以在类外使用this.loading
observable,例如,显示或隐藏基于observable值的加载器:
// logs to console each time loading state changes
serviceName.loading.subscribe(result => console.log(result));
不要忘记以后取消订阅,因为加载器是一个行为主体,它是多播的,如果不取消订阅,会导致内存泄漏。