代码之家  ›  专栏  ›  技术社区  ›  Milos

时滞递推可观测方法

  •  0
  • Milos  · 技术社区  · 5 年前

    我正在尝试创建递归的服务器连接方法,并在8中延迟。

    我试过这个:

    public connectToServerSafely(): Observable<boolean> {
      if (this.isConnecting) {
        return this.connectToServerSafely().pipe(delay(5000));
      } else if (this.isConnected) {
        return of(true);
      } else {
        return this.connectToServer();
      }
    }
    

    问题是这个延迟方法,我不知道为什么,但是在建立连接之前,我面临着将近2000次connectToServerSafely()方法调用。1秒后建立连接。

    为什么delay方法并没有真正地对connectToServerSafely方法进行postopone递归调用(像setTimeout方法那样)?

    0 回复  |  直到 5 年前
        1
  •  1
  •   Andrei Gătej    5 年前

    this.connectToServerSafely().pipe(delay(5000)) 不停地 函数无法调用自身。这个 delay 接线员会 延迟 发射值 .

    我的方法是:

    let isConnecting = true;
    let isConnected = false;
    
    timer(2000)
      .subscribe(() => (isConnecting = false, isConnected = true));
    
    function connSafely ()/* : Observable<any> */ {
      console.warn('calling `connSafely`');
    
      if (isConnecting) {
        return timer(500).pipe(concatMap(() => connSafely()))
      }
    
      if (isConnected) {
        return of(true);
      }
    
      return connectToServer();
    }
    
    function connectToServer () {
      isConnecting = true;
    
      return of('connecting');
    }
    
    connSafely().subscribe();
    

    console.warn("calling 'connSafely'") 初始函数调用 一个4,因为2000/500=4)。

    :您必须使用 higher-order mapping operators switchMap , concatMap , mergeMap / flatMap exhaustMap )以确保所有后续函数调用都自动订阅/取消订阅。

    尝试使用 tap(() => connSafely())

    StackBlitz . ( )

        2
  •  0
  •   Kasabucki Alexandr    5 年前

    看来你准备好了 this.isConnecting this.isConnected

    public connectToServerSafely(): Observable<boolean> {
      if (this.isConnecting) {
        // here function will be called until this.isConnecting change to false
        return this.connectToServerSafely().pipe(delay(5000));
      } else if (this.isConnected) {
        return of(true);
      } else {
        return this.connectToServer();
      }
    }
    
        3
  •  0
  •   Milos    5 年前

    这个解决方案适合我:

    public connectToServerSafely(): Observable<boolean> {
      if (this.isConnecting) {
        return new Observable((observer) => {
            setTimeout(() => {
              this.connectToServerSafely().subscribe(result => {
                observer.next(result);
                observer.complete();
              });
            }, 500);
          });
      } else if (this.isConnected) {
        return of(true);
      } else {
        return this.connectToServer();
      }
    }