RXJS平面映射到重复可观测

RXJS平面映射到重复可观测,rxjs,observable,ngrx,rxjs-pipeable-operators,rxjs-observables,Rxjs,Observable,Ngrx,Rxjs Pipeable Operators,Rxjs Observables,我正在尝试实现这项服务,它提供可观察的应用程序是否连接到我的服务器,所以当浏览器在线时,我们用定时器ping服务器。以下是代码: public get $connected(): Observable<boolean> { return this.hasInternetConnection .asObservable() .pipe( distinctUntilChanged(),

我正在尝试实现这项服务,它提供可观察的应用程序是否连接到我的服务器,所以当浏览器在线时,我们用定时器ping服务器。以下是代码:

public get $connected(): Observable<boolean> {
    return this.hasInternetConnection
               .asObservable()
               .pipe(
                 distinctUntilChanged(),
                 flatMap((connected: boolean) => {
                   if (!connected) {
                     return of(connected);
                   } else {
                     return timer(5000)
                       .pipe(
                         map(() => {
                           var success = Math.random() > 0.5;
                           console.log('PING: ' + success);
                           return success;
                         })
                       );
                   }
                 })
               );
  }
我怎样才能解决这个问题?谢谢大家!

完整解决方案:

  private hasInternetConnection: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(navigator.onLine);
  private connectedSubject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(true);
  private recheckConnectionSubject: Subject<void> = new Subject<void>();

  constructor(
    private readonly http: HttpClient,
  ) {
    fromEvent(window, 'online')
      .pipe(takeUntil(this.destroyed))
      .subscribe(() => {
        this.hasInternetConnection.next(true);
      });
    fromEvent(window, 'offline')
      .pipe(takeUntil(this.destroyed))
      .subscribe(() => {
        this.hasInternetConnection.next(false);
      });
    merge(
      this.hasInternetConnection,
      this.recheckConnectionSubject,
    )
      .pipe(
        mapTo(this.hasInternetConnection.value),
        switchMap((connected: boolean) => {
          if (!connected) {
            return of(connected);
          } else {
            return timer(0, 30000)
              .pipe(
                mergeMapTo(this.http.get(`${environment.apiRoot}/ping`, { responseType: 'text' })
                               .pipe(
                                 map((res) => {
                                   return true;
                                 }),
                                 catchError(() => {
                                   return of(false);
                                 })
                               )
                ),
              );
          }
        })
      )
      .subscribe(this.connectedSubject);
  }

  public get $connected(): Observable<boolean> {
    return this.connectedSubject.asObservable()
               .pipe(
                 distinctUntilChanged(),
               );
  }

  public resetTimer(): void {
      this.recheckConnectionSubject.next();
  }
private-has-internetconnection:BehaviorSubject=newbehaviorsubject(navigator.onLine);
private Connected Subject:BehaviorSubject=新的BehaviorSubject(true);
私有连接主体:主体=新主体();
建造师(
专用只读http:HttpClient,
) {
fromEvent(窗口“联机”)
.管道(直到(本次销毁))
.订阅(()=>{
this.hasInternetConnection.next(true);
});
fromEvent(窗口“脱机”)
.管道(直到(本次销毁))
.订阅(()=>{
this.hasInternetConnection.next(false);
});
合并(
这是一个互联网连接,
此.ConnectionSubject,
)
.烟斗(
mapTo(this.hasInternetConnection.value),
开关映射((已连接:布尔)=>{
如果(!已连接){
返回(已连接);
}否则{
返回计时器(0,30000)
.烟斗(
mergeMapTo(this.http.get(`${environment.apiRoot}/ping`,{responseType:'text'})
.烟斗(
地图((分辨率)=>{
返回true;
}),
捕获错误(()=>{
归还(假);
})
)
),
);
}
})
)
.订阅(本.连接主题);
}
public get$connected():可观察{
返回此.connectedSubject.asObservable()
.烟斗(
distinctUntilChanged(),
);
}
公共重置计时器():void{
this.ReconnectionSubject.next();
}
完整解决方案:

  private hasInternetConnection: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(navigator.onLine);
  private connectedSubject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(true);
  private recheckConnectionSubject: Subject<void> = new Subject<void>();

  constructor(
    private readonly http: HttpClient,
  ) {
    fromEvent(window, 'online')
      .pipe(takeUntil(this.destroyed))
      .subscribe(() => {
        this.hasInternetConnection.next(true);
      });
    fromEvent(window, 'offline')
      .pipe(takeUntil(this.destroyed))
      .subscribe(() => {
        this.hasInternetConnection.next(false);
      });
    merge(
      this.hasInternetConnection,
      this.recheckConnectionSubject,
    )
      .pipe(
        mapTo(this.hasInternetConnection.value),
        switchMap((connected: boolean) => {
          if (!connected) {
            return of(connected);
          } else {
            return timer(0, 30000)
              .pipe(
                mergeMapTo(this.http.get(`${environment.apiRoot}/ping`, { responseType: 'text' })
                               .pipe(
                                 map((res) => {
                                   return true;
                                 }),
                                 catchError(() => {
                                   return of(false);
                                 })
                               )
                ),
              );
          }
        })
      )
      .subscribe(this.connectedSubject);
  }

  public get $connected(): Observable<boolean> {
    return this.connectedSubject.asObservable()
               .pipe(
                 distinctUntilChanged(),
               );
  }

  public resetTimer(): void {
      this.recheckConnectionSubject.next();
  }
private-has-internetconnection:BehaviorSubject=newbehaviorsubject(navigator.onLine);
private Connected Subject:BehaviorSubject=新的BehaviorSubject(true);
私有连接主体:主体=新主体();
建造师(
专用只读http:HttpClient,
) {
fromEvent(窗口“联机”)
.管道(直到(本次销毁))
.订阅(()=>{
this.hasInternetConnection.next(true);
});
fromEvent(窗口“脱机”)
.管道(直到(本次销毁))
.订阅(()=>{
this.hasInternetConnection.next(false);
});
合并(
这是一个互联网连接,
此.ConnectionSubject,
)
.烟斗(
mapTo(this.hasInternetConnection.value),
开关映射((已连接:布尔)=>{
如果(!已连接){
返回(已连接);
}否则{
返回计时器(0,30000)
.烟斗(
mergeMapTo(this.http.get(`${environment.apiRoot}/ping`,{responseType:'text'})
.烟斗(
地图((分辨率)=>{
返回true;
}),
捕获错误(()=>{
归还(假);
})
)
),
);
}
})
)
.订阅(本.连接主题);
}
public get$connected():可观察{
返回此.connectedSubject.asObservable()
.烟斗(
distinctUntilChanged(),
);
}
公共重置计时器():void{
this.ReconnectionSubject.next();
}

示例2:计时器在1秒后发出,然后每2秒发出一次;“const source=timer(10002000);”示例2:计时器在1秒后发出,然后每2秒发出一次;常量源=计时器(10002000)