我如何连接可观察对象,但仅从最后一个中获取价值?

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 将同时发出 ab 每次当其中之一发生变化时。 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;
    });
  }
}

示例:https://stackblitz.com/edit/angular-combine-lates-with-interval-example-9vvqz7?file=src%2Fapp%2Fapp.component.ts

您可以使用 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>