我如何连接可观察对象,但仅从最后一个中获取价值?
How can I concat observables, but get value only from last of them?
这是我的 angular 应用中的示例:
concat(
obs1$,
obs2$,
obs3$
)
.subscribe() // Output: obs1$ value, obs2$ value, obs3$ value. Basically normal concat behaviour
这就是我想要实现的目标:
concatLast(
obs1$,
obs2$,
obs3$
)
.subscribe() // Output: obs3$ value
我不想使用skip()
、takeLast()
、switchMap()
end 等,因为重复代码太多而且看起来不太好,就像5 +观察。所以我想找到通用的解决方案。
也许有一些 RxJs 运算符或一些技巧可以让你做这样的事情
Combinelatest 将同时发出 a
和 b
每次当其中之一发生变化时。 a) 每 10 秒发射一次,b) 每 3 秒发射一次。
const a = stream('a', 10000, 10, 'partial');
const b = stream('b', 3000, 10, 'partial');
combineLatest(a, b).subscribe(fullObserver('latest'));
示例:https://stackblitz.com/edit/combine-latest-flsp5m?file=main.ts
在Angular中可能是这样的
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
mapResult: any;
from$: Subject<string> = new Subject<string>();
to$: Subject<string> = new Subject<string>();
searchTerm$ = combineLatest(this.from$, this.to$);
constructor() {}
ngOnInit() {
this.searchTerm$
.pipe(
debounceTime(1000),
switchMap((terms) => of(terms))
)
.subscribe((term: any) => (this.mapResult = term));
}
}
示例:https://stackblitz.com/edit/combinelatest-angular-army-qecyev
但不推荐使用of()
。所以这是一个更新的例子:
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
name = 'Angular Combine Lates With Interval Example';
subOne: BehaviorSubject<number> = new BehaviorSubject(0);
subTwo: BehaviorSubject<number> = new BehaviorSubject(0);
counterOne: number = 0;
counterTwo: number = 0;
data: [number, number];
ngOnInit() {
setInterval(() => {
this.subOne.next(++this.counterOne);
}, 2000);
setInterval(() => {
this.subTwo.next(++this.counterTwo);
}, 5000);
combineLatest(this.subOne, this.subTwo).subscribe((data) => {
console.log(data);
this.data = data;
});
}
}
您可以使用 last 运算符来过滤源 observable 发出的最后一项。
const { timer, concat } = rxjs;
const { mapTo, last } = rxjs.operators
const source1$ = timer(0).pipe(mapTo(1))
const source2$ = timer(50).pipe(mapTo(2))
const source3$ = timer(100).pipe(mapTo(3))
const result$ = concat(source1$, source2$, source3$).pipe(
last()
)
result$.subscribe(console.log)
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/7.4.0/rxjs.umd.min.js"></script>
如果您在代码中多次重复使用这段代码,您可以通过将此逻辑放入自定义运算符中来避免更多重复代码 (concatLast
)
const { timer, concat } = rxjs;
const { mapTo, last } = rxjs.operators
const source1$ = timer(0).pipe(mapTo(1))
const source2$ = timer(50).pipe(mapTo(2))
const source3$ = timer(100).pipe(mapTo(3))
const concatLast = (...sources) => concat(...sources).pipe(
last()
)
const result$ = concatLast(source1$, source2$, source3$)
result$.subscribe(console.log)
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/7.4.0/rxjs.umd.min.js"></script>
这是我的 angular 应用中的示例:
concat(
obs1$,
obs2$,
obs3$
)
.subscribe() // Output: obs1$ value, obs2$ value, obs3$ value. Basically normal concat behaviour
这就是我想要实现的目标:
concatLast(
obs1$,
obs2$,
obs3$
)
.subscribe() // Output: obs3$ value
我不想使用skip()
、takeLast()
、switchMap()
end 等,因为重复代码太多而且看起来不太好,就像5 +观察。所以我想找到通用的解决方案。
也许有一些 RxJs 运算符或一些技巧可以让你做这样的事情
Combinelatest 将同时发出 a
和 b
每次当其中之一发生变化时。 a) 每 10 秒发射一次,b) 每 3 秒发射一次。
const a = stream('a', 10000, 10, 'partial');
const b = stream('b', 3000, 10, 'partial');
combineLatest(a, b).subscribe(fullObserver('latest'));
示例:https://stackblitz.com/edit/combine-latest-flsp5m?file=main.ts
在Angular中可能是这样的
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit {
mapResult: any;
from$: Subject<string> = new Subject<string>();
to$: Subject<string> = new Subject<string>();
searchTerm$ = combineLatest(this.from$, this.to$);
constructor() {}
ngOnInit() {
this.searchTerm$
.pipe(
debounceTime(1000),
switchMap((terms) => of(terms))
)
.subscribe((term: any) => (this.mapResult = term));
}
}
示例:https://stackblitz.com/edit/combinelatest-angular-army-qecyev
但不推荐使用of()
。所以这是一个更新的例子:
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
name = 'Angular Combine Lates With Interval Example';
subOne: BehaviorSubject<number> = new BehaviorSubject(0);
subTwo: BehaviorSubject<number> = new BehaviorSubject(0);
counterOne: number = 0;
counterTwo: number = 0;
data: [number, number];
ngOnInit() {
setInterval(() => {
this.subOne.next(++this.counterOne);
}, 2000);
setInterval(() => {
this.subTwo.next(++this.counterTwo);
}, 5000);
combineLatest(this.subOne, this.subTwo).subscribe((data) => {
console.log(data);
this.data = data;
});
}
}
您可以使用 last 运算符来过滤源 observable 发出的最后一项。
const { timer, concat } = rxjs;
const { mapTo, last } = rxjs.operators
const source1$ = timer(0).pipe(mapTo(1))
const source2$ = timer(50).pipe(mapTo(2))
const source3$ = timer(100).pipe(mapTo(3))
const result$ = concat(source1$, source2$, source3$).pipe(
last()
)
result$.subscribe(console.log)
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/7.4.0/rxjs.umd.min.js"></script>
如果您在代码中多次重复使用这段代码,您可以通过将此逻辑放入自定义运算符中来避免更多重复代码 (concatLast
)
const { timer, concat } = rxjs;
const { mapTo, last } = rxjs.operators
const source1$ = timer(0).pipe(mapTo(1))
const source2$ = timer(50).pipe(mapTo(2))
const source3$ = timer(100).pipe(mapTo(3))
const concatLast = (...sources) => concat(...sources).pipe(
last()
)
const result$ = concatLast(source1$, source2$, source3$)
result$.subscribe(console.log)
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/7.4.0/rxjs.umd.min.js"></script>