Jon*_*wag 9 javascript reactive-programming rxjs typescript angular
上周我回答了一个 RxJS问题,在那里我与另一位社区成员进行了讨论:“我应该为每个特定的副作用创建订阅,还是应该尽量减少订阅?” 我想知道在完全反应式应用程序方法或何时从一种切换到另一种方法方面使用什么方法。这将帮助我和其他人避免不必要的讨论。
设置信息
什么是副作用(Angular 示例)
value$ | async)@Output event = event$)示例用例:
foo: () => void; bar: (arg: any) => voidhttp$: Observable<any>; click$: Observable<void>foo在http$发出后调用并且不需要值bar在click$发出后调用,但需要当前值http$案例:为每个特定的副作用创建订阅
const foo$ = http$.pipe(
mapTo(void 0)
);
const bar$ = http$.pipe(
switchMap(httpValue => click$.pipe(
mapTo(httpValue)
)
);
foo$.subscribe(foo);
bar$.subscribe(bar);
Run Code Online (Sandbox Code Playgroud)
案例:一般最小化订阅
http$.pipe(
tap(() => foo()),
switchMap(httpValue => click$.pipe(
mapTo(httpValue )
)
).subscribe(bar);
Run Code Online (Sandbox Code Playgroud)
简而言之我自己的看法
我可以理解订阅一开始会使 Rx 环境变得更加复杂的事实,因为您必须考虑订阅者应该如何影响管道或不影响管道(例如是否共享您的 observable)。但是,您将代码分离得越多(您越关注:什么时候会发生什么),将来维护(测试、调试、更新)代码就越容易。考虑到这一点,我总是为我的代码中的任何副作用创建一个单一的可观察源和一个单一的订阅。如果我的两个或多个副作用是由完全相同的源 observable 触发的,那么我会共享我的 observable 并单独订阅每个副作用,因为它可以有不同的生命周期。
RxJS 是管理异步操作的宝贵资源,应尽可能用于简化您的代码(包括减少订阅数量)。同样,如果 RxJS 提供了可以减少应用程序中订阅总数的解决方案,那么 observable 不应自动跟随对该 observable 的订阅。
但是,在某些情况下,创建并非严格“必需”的订阅可能会有所帮助:
一个示例异常 - 在单个模板中重用 observable
看你的第一个例子:
// Component:
this.value$ = this.store$.pipe(select(selectValue));
// Template:
<div>{{value$ | async}}</div>
Run Code Online (Sandbox Code Playgroud)
如果 value$ 在模板中只使用一次,我会利用异步管道及其代码经济性和自动取消订阅的好处。但是,根据此答案,应避免在模板中多次引用同一个异步变量,例如:
// It works, but don't do this...
<ul *ngIf="value$ | async">
<li *ngFor="let val of value$ | async">{{val}}</li>
</ul>
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我会创建一个单独的订阅并使用它来更新组件中的非异步变量:
// Component
valueSub: Subscription;
value: number[];
ngOnInit() {
this.valueSub = this.store$.pipe(select(selectValue)).subscribe(response => this.value = response);
}
ngOnDestroy() {
this.valueSub.unsubscribe();
}
// Template
<ul *ngIf="value">
<li *ngFor="let val of value">{{val}}</li>
</ul>
Run Code Online (Sandbox Code Playgroud)
从技术上讲,没有 也可以达到相同的结果valueSub,但应用程序的要求意味着这是正确的选择。
在决定是否订阅之前考虑 observable 的角色和生命周期
如果两个或多个 observable 仅在组合在一起时才有用,则应使用适当的 RxJS 运算符将它们组合成一个订阅。
类似地,如果first()被用来过滤掉除了第一次发出的 observable 之外的所有内容,我认为比起在会议。
如果任何单独的可观察量独立于其他可观察量是有用的,则单独订阅的灵活性和清晰度可能值得考虑。但根据我最初的声明,不应为每个 observable 自动创建订阅,除非有明确的理由这样做。
关于退订:
一个点对其他订购的是,更多的取消订阅要求。正如您所说,我们想假设所有必要的取消订阅都应用于 Destroy,但现实生活并不总是那么顺利!同样,RxJS 提供了有用的工具(例如first())来简化这个过程,从而简化代码并减少内存泄漏的可能性。本文提供了可能有价值的相关进一步信息和示例。
个人偏好/冗长与简洁:
请务必考虑您自己的喜好。我不想偏离关于代码冗长的一般性讨论,但目标应该是在过多的“噪音”和使您的代码过于神秘之间找到正确的平衡。这可能值得一看。
| 归档时间: |
|
| 查看次数: |
760 次 |
| 最近记录: |