5

有很多方法可以在一个组件中有效地处理多个订阅,我这里有两种方法,想知道哪种方法更有效,为什么?

方法一:使用数组

第 1 步:创建数组

private subscriptionArray: Subscription[];

第 2 步:向数组添加订阅

this.subscriptionArray.push(this._storeManagementHttp.createStore(newStore).subscribe(resp => {
  this._toast.success('New store created');
}));

步骤 3:迭代每个订阅和取消订阅

this.subscriptionArray.forEach(subs => subs.unsubscribe());

方法二

第 1 步:创建新订阅

private subscriptions = new Subscription();

第 2 步:添加订阅

this.subscriptions.add(this._storeManagementHttp.createStore(newStore).subscribe(resp => {
  this._toast.success('New store created');
  this._router.navigate(['/store-management']);
}));

Step3:清除订阅

this.subscriptions.unsubscribe();
4

4 回答 4

7

你也可以这个,在这种情况下你不需要运行循环

    private destroy$ = new Subject();
    
    myservice.megohd().pipe(takeUntil(destroy$)).subscribe();
    
    ngOnDestroy() {
      this.destroy$.next();
      this.destroy$.complete();
    }

在这里阅读(https://www.learnrxjs.io/operators/filtering/takeuntil.html

于 2019-06-21T11:18:46.410 回答
2

您还有第三个选项,即自定义 RxJS 运算符。

我创建了一个,发现Netanel Basal也找到了它,所以我会给出他的干净代码。

您可以安装UntilDestroyed或使用代码:

function isFunction(value) {
  return typeof value === 'function';
}

export const untilDestroyed = (
  componentInstance,
  destroyMethodName = 'ngOnDestroy'
) => <T>(source: Observable<T>) => {
  const originalDestroy = componentInstance[destroyMethodName];
  if (isFunction(originalDestroy) === false) {
    throw new Error(
      `${
        componentInstance.constructor.name
      } is using untilDestroyed but doesn't implement ${destroyMethodName}`
    );
  }
  if (!componentInstance['__takeUntilDestroy']) {
    componentInstance['__takeUntilDestroy'] = new Subject();

    componentInstance[destroyMethodName] = function() {
      isFunction(originalDestroy) && originalDestroy.apply(this, arguments);
      componentInstance['__takeUntilDestroy'].next(true);
      componentInstance['__takeUntilDestroy'].complete();
    };
  }
  return source.pipe(takeUntil<T>(componentInstance['__takeUntilDestroy']));
};

然后你的订阅变成

this.myService.subject.pipe(untilDestroyed(this)).subscribe(...);

请注意,由于 AOT 编译,您必须编写一个ngOnDestroy方法,否则操作员无法从头开始创建它。

于 2019-06-21T11:33:56.297 回答
0

尽管我会尽量避免使用上述所有方法并选择async“管道”,但您提供了很好的答案,即允许 Angular 进行订阅和取消订阅。

让我们考虑一些 Observables 说 5 observables

observale1$: Observable<IDataDto1>;
observale2$: Observable<IDataDto2>;
observale3$: Observable<IDataDto3>;
observale4$: Observable<IDataDto4>;
observale5$: Observable<IDataDto5>;

为了避免订阅所有这些,我们可以创建一个单一的Observablev$


import { forkJoin } from 'rxjs';
v$ = forkJoin({
  observale1: observale1$,
  observale2: observale2$,
  observale3: observale3$,
  observale4: observale4$,
  observale5: observale5$
});

有了上面的内容,我们可以将我们的component.html包装在一个*ngIf并允许 Angular 自动订阅和取消订阅


<ng-container *ngIf='v$ | async as v'>
  <!-- Your html code here -->
</ng-container>
于 2020-12-13T12:28:15.843 回答
0

我更喜欢方法2。

在方法1上没有问题。

它工作得很好。这种方法的问题在于我们将可观察流与普通的旧命令式逻辑混合在一起。

方法 2 是增强此方法的内置机制。

在这里阅读

于 2019-06-21T11:10:58.490 回答