是否有一个等效的异步管道,您可以在组件内使用?

Lev*_*Lev 10 reactive-programming rxjs angular

是否存在与async我可以在这样的组件内部使用的管道等效的东西

   @Component({
      selector: 'my-component',
    })

    export class myComponent {

      myObservable$: Observable<string>;

      method() {
        doSomething(this.myObservable$);
        // here I would like to access directly the current string value of
        // myObservable$ without having to subscribe 
      }
    }
Run Code Online (Sandbox Code Playgroud)

mag*_*tic 5

您必须问自己:您希望通过避免subscribe()通话来实现什么?我的猜测是,您希望避免保留订阅并必须手动取消订阅。

在这种情况下,您只需要确保获得一个完整的Observable即可。这样就无需以后取消订阅了。您可以将任何可观察的(有限的或无限的)转换为最终将完成的。

这是您的情况的示例:

  method() {
    this.myObservable$.take(1).subscribe(
      val => doSomething(val)
    );
  }
Run Code Online (Sandbox Code Playgroud)

正确的方法实际上取决于您的可观察对象做什么以及您希望如何使用该值。例如,Angular2 http调用自己完成,无需退订

或者,如果您想为可观察对象中的每个新值调用doSomething,则上述解决方案将不合适,因为您仅获得第一个值,然后可观察对象完成了。正如我所说,这取决于问题的背景。


max*_*992 5

不,没有。您需要手动订阅和手动取消订阅以避免内存泄漏。

对于简单的订阅,您可能会尝试这样做:

@Component({
  selector: 'my-component',
})
export class myComponent implements OnInit, OnDestroy {
  public myObservable$: Observable<string>;
  private myObservableSub: Subscription;

  ngOnInit() {
    this.myObservableSub = this
      .myObservable$
      .subscribe(_ => {
        // do something
      });
  }

  ngOnDestroy() {
    this.myObservableSub();
  }
}
Run Code Online (Sandbox Code Playgroud)

但是如果你有很多订阅呢?你应该做这样的事情:

@Component({
  selector: 'my-component',
})
export class myComponent implements OnInit, OnDestroy {
  public myObservable1$: Observable<string>;
  private myObservableSub1: Subscription;

  public myObservable2$: Observable<string>;
  private myObservableSub2: Subscription;

  public myObservable3$: Observable<string>;
  private myObservableSub3: Subscription;

  ngOnInit() {
    this.myObservableSub1 = this
      .myObservable1$
      .subscribe(_ => {
        // do something
      });

    this.myObservableSub2 = this
      .myObservable2$
      .subscribe(_ => {
        // do something
      });

    this.myObservableSub3 = this
      .myObservable3$
      .subscribe(_ => {
        // do something
      });
  }

  ngOnDestroy() {
    this.myObservableSub1();
    this.myObservableSub2();
    this.myObservableSub3();
  }
}
Run Code Online (Sandbox Code Playgroud)
**答案是不**

更新回复 (16/11/20)

在原始答案中(见此编辑之后),我建议使用 take until 但这会迫使您创建一个主题并在组件被销毁时触发一个事件。虽然这背后的想法很好,但在我们订阅流的所有组件中放入相当多的样板。

取而代之的是,我们可以创建一个自定义运算符,我们可以调用它takeUntilDestroyed并执行以下操作:

@Component({
  selector: 'my-component',
})
export class myComponent implements OnInit, OnDestroy {
  public myObservable1$: Observable<string>; // define your observable

  public myObservable2$: Observable<string>; // define your observable

  public myObservable3$: Observable<string>; // define your observable

  ngOnInit() {
    this
      .myObservable1$
      .pipe(takeUntilDestroyed(this))
      .subscribe(_ => {
        // do something
      });

    this.myObservableSub2 = this
      .myObservable2$
      .pipe(takeUntilDestroyed(this))
      .subscribe(_ => {
        // do something
      });

    this.myObservableSub3 = this
      .myObservable3$
      .pipe(takeUntilDestroyed(this))
      .subscribe(_ => {
        // do something
      });
  }

  ngOnDestroy() {}
}
Run Code Online (Sandbox Code Playgroud)

这个自定义运算符的实现可以在这里找到:https : //github.com/cloudnc/ngx-sub-form/blob/1115b21a007f72c54b521b3bed7c40051302145a/projects/ngx-sub-form/src/lib/shared/ngx-sub-form -utils.ts#L145-L148

原回复

您应该执行以下操作:

@Component({
  selector: 'my-component',
})
export class myComponent implements OnInit, OnDestroy {
  private componentDestroyed$ = new Subject<void>();

  public myObservable1$: Observable<string>;
  public myObservable2$: Observable<string>;
  public myObservable3$: Observable<string>;

  ngOnInit() {
    this
      .myObservable1$
      .takeUntil(componentDestroyed$)
      .subscribe(_ => {
        // do something
      });

    this
      .myObservable2$
      .takeUntil(componentDestroyed$)
      .subscribe(_ => {
        // do something
      });

    this
      .myObservable3$
      .takeUntil(componentDestroyed$)
      .subscribe(_ => {
        // do something
      });
  }

  ngOnDestroy() {
    this.componentDestroyed$.next();
    this.componentDestroyed$.complete();
  }
}
Run Code Online (Sandbox Code Playgroud)

如果你想了解更多,这里有一篇来自Ben Lesh的优秀文章:https : //medium.com/@benlesh/rxjs-dont-unsubscribe-6753ed4fda87

编辑:
感谢@olsn,我编辑了我的答案并添加了一行,next因为确实一个完整的不会停止其他流。

我创建了一个小的 Plunkr 来演示这种行为:https ://plnkr.co/edit/dcueDqUgpqgYimxEAGUn?p=preview

  • 你的 `this.componentDestroyed$.complete()` 不会停止任何流,你需要调用 `.next()` 因为 `complete` 只会完成流,但不会发出其他流可以响应的任何数据. (3认同)