有条件地返回基于Angular 5 observable.subscribe()内部的单个值,用于将异步调用链接在一起

问题描述 投票:0回答:1

我试图将两个异步调用链接到Spotify API - 一个获取播放列表的名称,另一个创建一个播放列表,如果它不存在于检索的播放列表列表中。目前,我确定播放列表是否已存在的代码如下所示:

  containsPlaylist(playlistToCreate: string): Observable<any> {
this.spotifyService.getUserPlaylists().flatMap(data => data.items).map((item: Track) => item.name).subscribe(name => {
  console.log(name);
  if (name === playlistToCreate) {
    console.log('returning true');
    return Observable.of(true);
  }
});
console.log('returning false');
return Observable.of(false);

}

但是,这显然是有缺陷的,因为异步调用getUserPlaylists()不必在到达“Observable.of(false)”语句之前返回。因此,即使调用最终返回,containsPlaylist也已返回false(据我所知)。我相信情况就是如此,因为控制台将按以下顺序打印console.log语句:

'return false','播放列表存在:false','创建播放列表','返回true'

下面是调用containsPlaylist的地方,它只检查函数是返回true还是false。

this.containsPlaylist(this.playlistToCreate).subscribe(playlistExists => {
  console.log('playlist exists: ' + playlistExists);
  if (!playlistExists) {
    console.log('creating playlist')
    this.spotifyService.createPlaylist(this.playlistToCreate, this.spotifyUser.id).subscribe(data => data);
  }
});

所以我的问题是:

如何让Observable.of(false)语句返回我的订阅内部,如Observable.of(true)语句?

或者,如果这是错误的思考方式,我如何修改containsPlaylist以正确返回getUserPlaylists返回的现有播放列表中是否包含playlistToCreate。谢谢!

angular typescript asynchronous observable spotify
1个回答
1
投票

你做得比实际困难得多。一般来说,当你有一个可观察的,但想要另一个,你不应该订阅。相反,您应该使用运算符:

containsPlaylist(playlistToCreate: string): Observable<boolean> {
  return this.spotifyService.getUserPlaylists().
    .map(arrayOfTracks => arrayOfTracks.some(track => track.name === playlistToCreate));
}

然后,如果第一个observable发出false,则可以使用switchMap而不是在订阅回调内部进行订阅:

this.containsPlaylist(this.playlistToCreate)
  .filter(result => !result)
  .switchMap(() => this.spotifyService.createPlaylist(this.playlistToCreate, this.spotifyUser.id))
  .subscribe(() => {});
© www.soinside.com 2019 - 2024. All rights reserved.