【问题标题】:How does combineLatest RxJS operator works when multiple observables emit values at the same time?当多个可观察对象同时发出值时,combineLatest RxJS 运算符如何工作?
【发布时间】:2023-01-11 05:11:09
【问题描述】:

RxJS Documentation 指出

结合最新组合多个 Observable 以创建一个 Observable,其值是根据每个输入 Observable 的最新值计算得出的。

我想了解如何结合最新当多个可观察对象同时发出值时有效吗?

如果我们看下面的代码

import 'zone.js/dist/zone';
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { bootstrapApplication } from '@angular/platform-browser';
import { timer, take, combineLatest } from 'rxjs';

@Component({
  selector: 'my-app',
  standalone: true,
  imports: [CommonModule],
  template: `Hello`,
})
export class App {
  name = 'Angular';

  constructor() {
    const a$ = timer(0, 1000).pipe(take(5)); //Emit values after each second (total 5 values)

    const b$ = timer(0, 4000).pipe(take(5)); //Emit values after every 4 seconds (total 5 values)

    //Marble Diagram
    
    //0 1 2 3 4
    //0       1       2       3       4

    const result$ = combineLatest(a$, b$);

    result$.subscribe((val) => console.log(val));
  }
}

bootstrapApplication(App);

输出如下 Output 在上面的输出中,在第 4 秒结果$observable 输出值 [4,0] 和 [4,1] 同时。

我的问题是,为什么它不只打印 [4,1],因为 combineLatest 带来了最新的价值,而“4”是来自 observable 的最新价值美元“1”是可观察到的最新值b$在第4秒。

Link to Demo

提前致谢!

【问题讨论】:

    标签: javascript angular rxjs rxjs-observables combinelatest


    【解决方案1】:

    你可以像这样使用它:

    import 'zone.js/dist/zone';
    import { Component } from '@angular/core';
    import { CommonModule } from '@angular/common';
    import { bootstrapApplication } from '@angular/platform-browser';
    import { timer, take, withLatestFrom } from 'rxjs';
    
    @Component({
      selector: 'my-app',
      standalone: true,
      imports: [CommonModule],
      template: `Hello`,
    })
    export class App {
      name = 'Angular';
    
      constructor() {
        const a$ = timer(0, 1000).pipe(take(5)); //Emit values after each second (total 5 values)
    
        const b$ = timer(0, 4000).pipe(take(5)); //Emit values after every 4 seconds (total 5 values)
    
        const result$ = a$.pipe(withLatestFrom(b$, (a, b) => [a, b]));
    
        result$.subscribe((val) => console.log(val));
      }
    }
    
    bootstrapApplication(App);
    

    https://stackblitz.com/edit/angular-gsyobe?file=src/main.ts

    【讨论】:

    • 这提供了与combineLastest 不同的行为。 combineLastest 将在 a$b$ 发出时发出。此解决方案仅在 a$ 发出时发出。
    【解决方案2】:

    在每个源发出至少一个值后,combineLatest 会在其任何源可观察量发出时发出。

    即使两个可观察量“同时”发出(我假设你的意思是在同一个事件循环中), combineLatest 会发射两次。

    如果你想防止在同一个事件循环中发生排放,你可以使用debounceTime(0)

    result$ = combineLatest(a$, b$).pipe(debounceTime(0));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-23
      • 2022-11-09
      • 2020-12-26
      • 1970-01-01
      • 2018-12-02
      相关资源
      最近更新 更多