角度:使用Observable的异步请求。等待完全获取

时间:2019-02-27 18:46:39

标签: angular asynchronous

我一直在尝试找出处理异步请求和可观察对象的正确方法或最佳实践,但是我似乎找不到简单的东西。另外,还有很多建议使用Promises代替Observables的东西,但是我读到Observables的处理要灵活得多。所以我想继续使用Observables。

所以基本上,我的服务类中的函数是这样的。

getUserTop(spotifyRequestType, timeRange, resultLimit): Observable<any>{
    return this.httpClient.post<Observable<any>>('http://localhost:3000/getUserTop', {
      spotifyRequestType: spotifyRequestType, //artist or track
      timeRange: timeRange, //between short_term, medium_term, long_term
      resultLimit: resultLimit //number of results to be displayed
    }).pipe(catchError(this.handleError));
  }

  getRecommendations(seed_artists):Observable<any> {
      return this.httpClient.post<Observable<any>>('http://localhost:3000/getRecommendations', 
    {
      seed_artists : seed_artists
    }
    ).pipe(catchError(this.handleError));  
  }

 createPlaylist(playlistName, playlistDesc, isPublic, tracks): Observable<any>{
    return this.httpClient.post<Observable<any>>('http://localhost:3000/createPlaylist', {
      playlistName: playlistName, //name of the playlist
      playlistDesc: playlistDesc,  //desc of the playlist
      isPublic: isPublic, //public or private indicator
      tracks: tracks //tracks to be added to the playlist
    }).pipe(catchError(this.handleError));
  }

我正在localhost:3000上运行Node.js服务器。 get函数只是从Node

获取JSON对象。
  1. 获得顶级艺术家。
  2. 获取基于艺术家的推荐曲目。
  3. 创建播放列表并添加曲目。

这些是我的方法。

getTopArtists(spotifyRequestType, timeRange, resultLimit): String {
    var artistList = '';
    this.spotifyService.getUserTop(spotifyRequestType, timeRange, resultLimit).subscribe(
      data => {
        for(var i=0; i<data['items'].length; i++ ){
          artistList += data['items'][i]['id'];
        }  
      }
    ) 
    return artistList;
  }

  getRecommendations(artist): String[]{
    var trackList = [];
    this.spotifyService.getRecommendations(artist).subscribe(
      data => {
        for(var i=0; i<data['items'].length; i++ ){
          trackList.push(data['items'][i]['id']); 
        }  
      }
    ) 
    return trackList;    
  }

  addRecommendationsToPlaylist(playlistName, playlistDescription, isPublic, tracks){
    this.spotifyService.createPlaylist(playlistName, playlistDescription, isPublic, tracks).subscribe(
      data => {
        console.log(data);
      })

  }

  publishPlaylistToSpotify(){
    var topArtists = this.getTopArtists('artists', 'short_term', '5' ); //Get a user's recent top 5 artists.
    var trackList = this.getRecommendations(topArtists); //Get a list of tracks based on top artists.
    this.addRecommendationsToPlaylist('My Playlist', 'My Playlist Description', 'false', trackList); //Create a playlist and add tracks to it.
  }

现状,由于方法包含异步请求,因此publishPlaylistToSpotify()将不起作用,因为执行不等待topArtists和trackList被完全获取。在我的publishPlaylistToSpotify()中,如何确保首先完全获取topTopArtists,然后完全获取trackList,然后继续创建播放列表?

1 个答案:

答案 0 :(得分:0)

getTopArtistsgetRecommendations进行数据异步调用。因此,他们还应该返回承诺或可观察的结果。有关如何使用javascript中的异步调用的信息,请参见建议的副本。

对于以javascript中的异步调用开始的用户,我建议使用async/await,因为生成的代码类似于同步调用。重构并应用异步/等待,请参见下面的代码。

async getTopArtists(spotifyRequestType, timeRange, resultLimit): Promise<String> {
    var artistList = '';
    var data = await this.spotifyService.getUserTop(spotifyRequestType, timeRange, resultLimit).toPromise();
    for(var i=0; i<data['items'].length; i++ ){
      artistList += data['items'][i]['id'];
    }
    return artistList;
}

async getRecommendations(artist): Promise<String[]> {
    var trackList = [];
    var data = await this.spotifyService.getRecommendations(artist).toPromise();
    for(var i=0; i<data['items'].length; i++ ){
      trackList.push(data['items'][i]['id']); 
    }  
    return trackList;
}

addRecommendationsToPlaylist(playlistName, playlistDescription, isPublic, tracks){
    this.spotifyService.createPlaylist(playlistName, playlistDescription, isPublic, tracks)
        .subscribe(data => { console.log(data); });
}

async publishPlaylistToSpotify() {
    var topArtists = await this.getTopArtists('artists', 'short_term', '5' ); //Get a user's recent top 5 artists.
    var trackList = await this.getRecommendations(topArtists); //Get a list of tracks based on top artists.
    this.addRecommendationsToPlaylist('My Playlist', 'My Playlist Description', 'false', trackList); //Create a playlist and add tracks to it.
}