Typescript RxJS中切换订阅的最优雅方式
由于我已经是一名经验丰富的.NET开发人员,我正在学习新技术,我很好奇您如何在TypeScript+RxJS中解决这个问题。 比如说,我有多个列(字段),我正在观察它们的值的变化。我还有一个开关,它有一组列要观察——在这个例子中是1,2,3;A、 B,C和X,Y,Z 每次我必须切换时,我都希望从以前的组中删除订阅,并为新组创建订阅。代码如下所示:Typescript RxJS中切换订阅的最优雅方式,typescript,rxjs,Typescript,Rxjs,由于我已经是一名经验丰富的.NET开发人员,我正在学习新技术,我很好奇您如何在TypeScript+RxJS中解决这个问题。 比如说,我有多个列(字段),我正在观察它们的值的变化。我还有一个开关,它有一组列要观察——在这个例子中是1,2,3;A、 B,C和X,Y,Z 每次我必须切换时,我都希望从以前的组中删除订阅,并为新组创建订阅。代码如下所示: const log = (cid: string) => console.info(`${cid} changed`); this.subsc
const log = (cid: string) => console.info(`${cid} changed`);
this.subscriptions.add(this.observeValueChanges("column 1").subscribe(log));
this.subscriptions.add(this.observeValueChanges("column 2").subscribe(log));
this.subscriptions.add(this.observeValueChanges("column 3").subscribe(log));
//Switching to another columns collection - I don't want previous subscriptions anymore
this.subscriptions.unsubscribe();
this.subscriptions.add(this.observeValueChanges("column A").subscribe(log));
this.subscriptions.add(this.observeValueChanges("column B").subscribe(log));
this.subscriptions.add(this.observeValueChanges("column C").subscribe(log));
//Switching to another columns collection - I don't want previous subscriptions anymore
this.subscriptions.unsubscribe();
this.subscriptions.add(this.observeValueChanges("column X").subscribe(log));
this.subscriptions.add(this.observeValueChanges("column Y").subscribe(log));
this.subscriptions.add(this.observeValueChanges("column Z").subscribe(log));
供参考:
private subscriptions: Subscription = new Subscription();
及
observeValueChanges(columnId:string):可观察{
返回计时器(0,1000).pipe(map(=>columnId),publish(),refCount());
}
我可以通过用订阅数组替换订阅对象使其工作,切换后-我可以从数组中全部取消订阅(而不是添加-我可以推送)。
你喜欢什么?我对将“开关信号”设置为可观察状态没有问题。有趣的是,您使用了“开关”一词,因为您正在寻找的操作员被称为 每当接收到一个新值时,它都会将其“映射”到一个可观测值,并从以前的源“切换”
switchMap
是一个“”,它为您做了几件好事:
这是一个很好的答案,我完全可以在我的解决方案中使用它!好东西!很高兴有帮助!:-)
observeValueChanges(columnId: string): Observable<any> {
return timer(0, 1000).pipe(map(_ => columnId), publish(), refCount());
}
import { fromEvent } from 'rxjs';
import { tap, map, switchMap } from 'rxjs/operators';
const group0 = document.querySelectorAll('.group0');
const group1 = document.querySelectorAll('.group1');
const selectedGroup = document.querySelectorAll('.selected-group');
// Array of possible sources to "switch" between
//
// [fromEvent] Creates an observable that emits DOM
// events for the specified elements.
//
// [map] Just maps the event to the target value.
const sources$ = [
fromEvent(group0, 'keyup').pipe(map(event => event.target['value'])),
fromEvent(group1, 'keyup').pipe(map(event => event.target['value']))
];
// selectedGroup$ emits the value of the selected radio button which
// for this example is conveniently the group's index in the array.
const selectedGroup$ = fromEvent(selectedGroup, 'change').pipe(
map(event => event.target['value'])
);
// source$ starts with the emission of selectedGroup$. Then we
// use [switchMap] to "switch" our source observable and map
// it to a new observable source. Then switchMap will
// automatically unsubscribe from the previous one.
const source$ = selectedGroup$.pipe(
switchMap(groupIndex => sources$[groupIndex])
)
// Notice we only need a single subscription!
source$.subscribe(console.log);