【发布时间】:2021-11-15 07:13:44
【问题描述】:
有没有办法检测管道内可观察的 rxjs 订阅的开始?
我想在订阅 http observable(在响应完成后销毁)时触发加载指示器。
或者我是否必须为此操作创建一个可观察的包装器?
【问题讨论】:
标签: angular typescript rxjs
有没有办法检测管道内可观察的 rxjs 订阅的开始?
我想在订阅 http observable(在响应完成后销毁)时触发加载指示器。
或者我是否必须为此操作创建一个可观察的包装器?
【问题讨论】:
标签: angular typescript rxjs
这取决于您使用的 RxJS 版本。使用 RxJS defer():
defer(() => {
loadingFlag = true;
return this.http.doyourrequest().pipe(
finalize(() => loadingFlag = false),
);
});
由于 RxJS >= 7.3,您可以为 tap() 使用新的事件处理程序:
this.http.doyourrequest().pipe(
tap({
subscribe: () => loadingFlag = true,
finalize: () => loadingFlag = false,
}),
);
【讨论】:
由于每次订阅 http observable 都会导致新的 http 调用,因此在管道外设置此类标志是安全的,至少我是这样做的。
getSomeData(){
loadingFlag=true;
return this.http.doyourrequest().pipe(finalize(()=>loadingFlag=false));
}
如果你真的想通过子计数(由于 http obs 的最终化,每次请求后总是下降到 0)检查 refCount() 和 share() 内部计算订阅者的操作符的实现
编辑:
您可以使用 dummy observable 作为入口点来封装标志的设置,例如
getSomeData(){
return of(null).pipe(
tap(()=>loadingFlag=true),
switchMapTo(this.http.doyourrequest()),
finalize(()=>loadingFlag=false)
)
}
【讨论】:
不要在流中设置一些指示符作为副作用,而是尝试创建一个返回请求状态的可观察对象。
readonly makeRequestSubject = new Subject<RequestParams>();
readonly request$ = makeRequestSubject.pipe(
switchMap(params => this.doRequest(params).pipe(
map(result => ({ params, result, state: 'complete' })),
catchError(error => ({ error, params, state: 'error' }))
startWith({ params, state: 'loading' })
),
startWith({ state: 'notstarted' }),
shareReplay(1)
);
readonly isLoading$ = this.request.pipe(map(x => x === 'loading'), distinctUntilChanged());
readonly results$ = this.request.pipe(map(x => x === 'complete' ? x.results : []));
【讨论】: