【问题标题】:How to combine get .pipe takeUntil and subscribe into one function in Angular with RxJX?如何将 get .pipe takeUntil 和订阅 Angular 中的一个函数与 RxJS 结合起来?
【发布时间】:2019-10-08 09:16:33
【问题描述】:

在 Angular 中,每次需要查询端点时,都需要调用这段代码:

this.service.getSomeData()
 .pipe(takeUntil(this.onDestroy$))
 .subscribe((message: any) => { 
    some code here; 
 }

takeUntil 是组件中的一个函数,用于在组件被销毁时取消订阅。

如何重构上面的代码,以便在每次使用资源时都不需要输入所有这些?所以最后看起来像这样(或多或少?):

this.service.getSomeData(
   (message: any) => {
     some code here;
   }
)

【问题讨论】:

    标签: javascript angular rxjs frontend


    【解决方案1】:

    通常,在从视图/dom 卸载某些组件后,您的服务不必被销毁/禁用。将它们视为执行某些数据转换或获取的代码层。


    问:为什么大家都用takeUntil(this.destroyed$)this.subscription.unsubscribe()

    答:Observable 只要有至少一个订阅者,它就会一直存在。因此,如果您有一些长期存在的可观察对象在某些操作后没有立即完成,那么您将出现内存泄漏(Angular 可以多次创建/初始化每个组件)。说到Angularhttp,所有getpostputdelete调用都是在后端调用完成后完成的。这意味着您不必在onDestroy 挂钩中添加unsubscribe 或使用takeUntil

    如果您已建立Websocket 连接并正在收听一些消息,则您的流将变得持久,并且订阅此消息的每个组件应该onDestroy 周期内取消订阅。如果你不这样做,Angular 可以多次初始化你的组件(这通常发生在*ngIf="" 语句中)并且创建多个订阅但永远不会销毁。这会导致内存泄漏。

    不幸的是,这是大多数 Angular 项目的常见问题,可以通过手动 unsubscribe/takeUntil 或使用在组件销毁后自动执行 unsubscribeasync 管道来解决。

    【讨论】:

      【解决方案2】:

      一种选择是使用模板中的异步管道来管理订阅

      data$ = this.service.getSomeData();
      

      在你的模板中

      <ng-container *ngIf="data$ | async as data">
        {{ data | json }}
        You can use the template variable data here that magically updates every time data$
        emits and no need to unsubscribe as the async pipe manages the subscription for you
      </ng-container>
      

      如果 observable 发出的数据不是模板所需的形状,则使用映射函数

      data$ = this.service.getSomeData().pipe(map(data => functionThatTransformsData(data)));
      

      你可以在这里https://medium.com/@adrianbrand/angular-state-management-with-rxcache-468a865fc3fb阅读我的状态管理库使用的模式

      【讨论】:

        【解决方案3】:

        很高兴你这么问, 我遇到了这个Angular AutoUnsubscribe(我引用这个是因为我发现实现它的逻辑真的很漂亮。)

        它相对易于使用,并且适用于所有可声明对象(显然是管道、指令和组件。)

        现在省略订阅和取消订阅部分(我不会建议),它非常简单,直接。

        之前你有类似的东西

        getSomeData(): Observable<any> {
          // for eg
          return this.http.get();
        }
        

        你必须把它改成:

        getSomeData(callback, onDestroy$): Observable<any> {
          this.http.get(...).pipe(takeUntil(onDestroy$)).subscribe(val => callback(val));
        }
        

        然后我们就能得到我们最终想要的东西。 干杯。

        【讨论】:

          猜你喜欢
          • 2023-03-24
          • 1970-01-01
          • 1970-01-01
          • 2017-12-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-06-09
          • 2017-11-25
          相关资源
          最近更新 更多