如何在X秒未收到gRPC流(Observable)数据时隐藏绑定div
实现方案
核心使用RxJS的switchMap+timer组合实现超时检测逻辑,无需修改原有Service代码,侵入性极低:每次收到gRPC流数据时先赋值变量,同时启动超时计时器,若计时器到期前没有新数据流入,就自动将绑定变量设为null,反之则自动取消旧计时器重启计时。
代码修改示例
1. Component.ts修改
import { Component, AfterViewInit, OnDestroy } from '@angular/core'; import { Subscription, merge, of, timer } from 'rxjs'; import { switchMap, endWith, map } from 'rxjs/operators'; // 定义无数据超时时间,单位为毫秒,可根据业务调整 const NO_DATA_TIMEOUT = 5000; // 示例为5秒无数据则隐藏div export class AppComponent implements AfterViewInit, OnDestroy { public testReply?: TestReply.AsObject | null; private _subscription: Subscription = new Subscription(); constructor(private readonly _MyTestService: ApiMyTestService) {} public ngAfterViewInit(): void { this._subscription = this._MyTestService.testData$.pipe( switchMap(data => merge( // 立刻返回收到的真实流数据,赋值后显示div of(data), // 启动超时计时器,到期后返回null,有新数据时switchMap会自动取消该计时器 timer(NO_DATA_TIMEOUT).pipe(map(() => null)) )), // 可选:流正常结束/报错时也自动输出null,隐藏div endWith(null) ).subscribe(data => { this.testReply = data; }); } ngOnDestroy(): void { // 组件销毁时取消订阅,避免内存泄漏 this._subscription?.unsubscribe(); } }
2. HTML语法修正
原代码*ngIf语法缺少引号,修正后如下:
<!-- 仅当存在流数据时显示该div,X秒无绑定数据时自动隐藏 --> <div *ngIf="testReply"> 使用testReply的HTML元素 </div>
逻辑说明
switchMap的特性是每当上游发送新值,就会自动取消上一次创建的内部Observable,因此旧的超时计时器会被自动销毁,不会出现重复触发的问题- 若需要gRPC流断开后自动重连,可在pipe中追加
retry()操作符即可实现自动重连逻辑
内容的提问来源于stack exchange,提问作者mv_05
相关产品推荐
相关产品推荐

