簡體   English   中英

在 RxJS 中處理並行嵌套的 observables

[英]Handling parallel nested observables in RxJS

我正在清理項目中嵌套的並行 observable,但在處理 observable 事件時遇到了一些問題。 這是我的音樂應用程序中的一種情況,我加載播放列表頁面並需要加載播放列表數據、用戶信息以及用戶是否關注播放列表:


  • Route Observable(從 URL返回參數,我需要提取playlistId
    • Playlist Observable(需要playlistId返回PlaylistObject並解析)
    • 用戶可觀察(返回UserObject
      • IsUserFollowing Observable(需要playlistIdUserObject.id並在用戶關注播放列表時返回T/F)

總之,我從 Angular 的Route observable 接收到 route 參數,我需要並行觸發另外兩個 observable, Playlist ObservableUser Observable 一旦播放列表數據返回, Playlist Observable就可以解析,但是User Observable需要繼續處理另一個 observable IsFollowingUser ,直到它可以解析。

這是我當前使用嵌套 observable 的(錯誤的)實現:

this.route.params.pipe(
  first()
).subscribe((params: Params) => {

  this.playlistId = parseInt(params["playlistId"]);

  if (this.playlistId) {

    this.playlistGQL.watch({ 
      id: this.playlistId,
    }).valueChanges.pipe(
      takeUntil(this.ngUnsubscribe)
    ).subscribe((response) => { 
      this.playlist = response; // use this to display playlist information on HTML page
      this.playlistTracks = response.tracks; //loads tracks into child component
    });

    this.auth.user$.pipe(
      filter(stream => stream != null)
    ).subscribe((user) => {
      this.user = user;
      this.userService.isFollowingPlaylist(this.user.id, this.playlistId).subscribe((response) => {
        this.following = response; //returns a T/F value that I use to display a follow button
      })
    })

  }

這有效,但顯然不遵循 RxJS 最佳實踐。 像這樣清理嵌套的並行 observable 的最佳方法是什么?

這是我會做的事情,盡管這可能不是最佳的,但可能比以前更好。

我將假設前面的代碼塊在ngOnInit

async ngOnInit() {
  // get the params as if it is a promise
  const params: Params = await this.route.params.pipe(
                                      first()
                                    ).toPromise();

  this.playlistId = parseInt(params["playlistId"]);
  if (this.playlistId) {
    // can name these functions to whatever you like (better names)
    this.reactToPlaylistGQL();
    this.reactToUser();
  }
}

private reactToPlaylistGQL() {
  this.playListGQL.watch({
    id: this.playListId,
  }).valueChanges.pipe(
   takeUntil(this.ngUnsubscribe)
 ).subscribe(response => {
   this.playlist = response;
   this.playlistTracks = response.tracks;
 });
}

private reactToUser() {
  this.auth.user$.pipe(
    filter(stream => stream != null),
    // switch over to the isFollowingPlaylist observable
    switchMap(user => {
     this.user = user;
     return this.userService.isFollowingPlaylist(this.user.id, this.playListId);
   }),
    // consider putting a takeUntil or something of that like to unsubscribe from this stream
  ).subscribe(response => this.following = response);
}

我發現將if (this.playlistId)塊中的函數命名為人類友好的名稱使得無需編寫注釋(描述性函數名稱說明它應該做什么)並且看起來比放置 RxJS 流的 blob 更清晰。

我是徒手寫的,所以可能會有一些錯別字。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM