简体   繁体   English

如何将 get.pipe takeUntil 和订阅到 Angular 中的一个 function 和 RxJX 结合起来?

[英]How to combine get .pipe takeUntil and subscribe into one function in Angular with RxJX?

In Angular every time a endpoint needs to be queried, this code needs to be called:在Angular中,每次需要查询一个端点时,都需要调用这段代码:

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

takeUntil is a function in a component to unsubscribe when component is destroyed. takeUntil 是组件中的 function 在组件被销毁时取消订阅。

How to refactor the code above so it wont be needed to type all of this every time a resource is used?如何重构上面的代码,以便每次使用资源时都不需要输入所有这些? So it looks like this at the end (more or less?):所以最后看起来像这样(或多或少?):

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

One option is to use the async pipe in your template to manage the subscriptions一种选择是在模板中使用异步 pipe 来管理订阅

data$ = this.service.getSomeData();

and in your template并在您的模板中

<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>

If the observable emits data that is not in the shape you need for your template then use a map function如果 observable 发出的数据不是模板所需的形状,则使用 map function

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

You can have a read of the pattern I use with my state management library here https://medium.com/@adrianbrand/angular-state-management-with-rxcache-468a865fc3fb您可以在此处阅读我在 state 管理库中使用的模式https://medium.com/@adrianbrand/angular-state-management-with-rxcache-468a865fc3fb

Generally your services don't have to be destroyed/disabled after some component is unmounted from view/dom.通常,在从视图/dom 卸载某些组件后,您的服务不必被销毁/禁用。 Treat them like a layer of code to perform some data transformation or fetching.把它们当作一层代码来执行一些数据转换或获取。


Q: Why does everyone use takeUntil(this.destroyed$) or this.subscription.unsubscribe() ?问:为什么每个人都使用takeUntil(this.destroyed$)this.subscription.unsubscribe()

A: The Observable lives as long as there is at least one subscriber for it.答:只要至少有一个订阅者, Observable就会存在。 So if you have some long-living observables that are not completed immediately after some action, you will have memory leaks (Angular can create/initialize each component multiple times).因此,如果您有一些长期存在的可观察对象在某些操作后没有立即完成,您将有 memory 泄漏(Angular 可以多次创建/初始化每个组件)。 Speaking of Angular 's http , all of get , post , put and delete calls are completed after the backend call is done.说到Angularhttp ,所有的getpostputdelete调用都是在后端调用完成后完成的。 This means that you don't have to add unsubscribe in onDestroy hook or use takeUntil .这意味着您不必在onDestroy挂钩中添加unsubscribe或使用takeUntil

If you have established a Websocket connection and are listening to some messages, your stream become long-lasting and each component that is subscribed to this messaged should unsubscribe during onDestroy cycle.如果您已建立Websocket连接并正在收听一些消息,则您的 stream 将变得持久,并且订阅此消息的每个组件都应onDestroy周期内取消订阅。 If you don't do this, Angular can initialize your component multiple times (this usually happens with *ngIf="" statements) and multiple subscriptions are created but never destroyed.如果你不这样做,Angular 可以多次初始化你的组件(这通常发生在*ngIf=""语句中)并且多个订阅被创建但永远不会被销毁。 This leads to memory leaks.这会导致 memory 泄漏。

Unfortunately this is a common problem for most of the Angular projects that can be solved by either manual unsubscribe / takeUntil or by using the async pipe that automatically performs unsubscribe after the component is destroyed.不幸的是,这是大多数 Angular 项目的常见问题,可以通过手动unsubscribe / takeUntil或使用async pipe 在组件被销毁后自动执行unsubscribe来解决。

I am glad you asked that, I came across this Angular AutoUnsubscribe (I am referencing this because I found that the logic to implement this is really beautiful.)我很高兴你问这个,我遇到了这个Angular AutoUnsubscribe (我引用这个是因为我发现实现这个的逻辑真的很漂亮。)

Its relatively easy to use, and workes across all declarables(pipes, directives, and components obviously.)它相对易于使用,并且适用于所有可声明对象(显然是管道、指令和组件。)

Now to omit both the subscribing and unsubscribing part (that I won't suggest), it pretty simple, and straight forward.现在省略订阅和取消订阅部分(我不会建议),它非常简单,直截了当。

Earlier you had something like早些时候你有类似的东西

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

You have to Change it to:您必须将其更改为:

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

Then we'll be able to have what we finally wanted.然后我们就能得到我们最终想要的东西。 Cheers.干杯。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM