在BehaviorSubject Observable 上执行操作符不起作用

mat*_*c19 5 rxjs angular

我有一个 Angular 应用程序,我试图将预订列表从服务器下载到 Angular 服务。我想让所有组件都能够将预订数组作为可观察的,并能够过滤和限制结果。现在我正在使用BehaviorSubject。这是我的代码。

//reservation.service.ts (partial code)

@Injectable()
export class TripService {
  public Trips: Object[] = [];
  public TripSubject: Subject<Object[]> = new BehaviorSubject<Object[]>([]);
  public trips$: Observable<Object[]> = this.TripSubject.asObservable();

  constructor(private apollo: Apollo) { 
    this.apollo.query({query: ReservationQuery}).subscribe((trips: any) => {
      this.Trips = trips.data.allReservations;      
      this.TripSubject.next(this.Trips)
    })
  }
}

//partial component

ngOnInit(): void {   
  this.tripService.trips$.take(3).subscribe(trips => {
    this.Trips = trips
  })
}
Run Code Online (Sandbox Code Playgroud)

我得到了要填充的预订,但我得到了所有的预订,而不仅仅是通过使用 take(3) 得到了我想要的 3 个。take 操作符不工作有什么原因吗?

Coz*_*ure 3

正如 @Yakov Fain 所说,您将在一次 next() 调用中将整个数组发送到主题。

如果没有充分的理由将对象数组转换为 数组Observables,只需.slice()在数组中执行以下操作:

ngOnInit(): void {   
  this.tripService.trips$.subscribe(trips => {
    this.Trips = trips.slice(0,3)
  })
}
Run Code Online (Sandbox Code Playgroud)

否则,如果您确实想将其转换为 Observables 序列(以便您可以使用.take(3)),那么您将需要使用.from()

ngOnInit(): void {
    this.tripService.trips$
        .switchMap(trips => Observable.from(trips));
        .take(3)
        .subscribe(trips=>{
            this.Trips = trips;
        });
}
Run Code Online (Sandbox Code Playgroud)

请注意,获取对象数组和 Observables 数组的根本区别在于后者具有多个事件发射。

区别如下:

对象数组的单个 Observable,使用.slice()

const arr = [1, 2, 3, 4, 5];
const observables = Observable.of(arr);

observables
    .subscribe(x => {
        this.Trips = x.slice(0, 3)
        console.log(this.Trips);
    });
    //output: [1,2,3] 
    //this.Trips is an array of length 3.
Run Code Online (Sandbox Code Playgroud)

从对象数组派生的多个 Observables,使用.from()

const arr = [1, 2, 3, 4, 5];
const observables = Observable.from(arr);

observables
    .take(3)
    .subscribe(x => {
        this.Trips = x;
        console.log(this.Trips);
    });
    //output: 1
    //output: 2
    //output: 3
    //You got a single digit output, each are replaces the value of this.Trips on every emission.
Run Code Online (Sandbox Code Playgroud)