我想使用RxJS实现加载指示(微调器和下面的消息(。
- 从0到30秒,消息将是"正在处理您的请求…">
- 30秒后,消息将是"您的请求正在处理中。。。,它通常只需要不到一分钟的时间
如果数据在30秒内成功到达,则带有消息的加载程序将消失。
我正在Angular项目中实现这一点。下面的代码是一种草案版本,它没有按预期工作,因为api数据等待计时器完成
public initializeDashboard() {
const timerMessage$ = timer(30000, 1000).pipe(take(1));
const dashboard$: Array<any> = this.headerService.getItems();
this.progressMessage = 'Your request is being processed...';
merge(timerMessage$, dashboard$).pipe(
tap((item) => {
if (isNumber(item)) {
this.progressMessage = 'Usually it takes less then a minute';
}
}),
filter(item => isArray(item)))
.subscribe(
(responseData) => {
this.progressMessage = '';
this.responseData = responseData,
}
);
}
这里的技巧是,我将合并两个链,其中第一个链只会产生副作用并更新消息,而第二个链是使用take(1)
可以完成链的链。这是必要的,因为当CCD_ 2发射。
我认为还有另一个没有ignoreElements()
的变体,但这也需要takeUntil()
和share()
,并进行两个单独的订阅,所以我认为这是更容易的一个。
public initializeDashboard() {
const dashboard$: Array<any> = this.headerService.getItems();
const timerMessage$ = timer(30 * 1000) // This will emit just once after 30s
.pipe(
tap(() => this.progressMessage += 'Usually it takes less then a minute'),
ignoreElements(), // all emission will be ignored so they won't reach `take(1)` and complete the chain
);
this.progressMessage = 'Your request is being processed...';
merge(timerMessage$, dashboard$)
.pipe(
take(1), // This is required so when `dashboard$` emits it will unsubscribe from `timerMessage$` automatically
)
.subscribe((responseData) => {
this.progressMessage = '';
this.responseData = responseData,
});
}