如何仅在执行并完成 n 个 HTTP 请求列表后才执行 HTTP 请求

How to execute an HTTP request only after a list of n HTTP requests have been executed and completed

我正在使用 Spotify 的 Web Api。

我有一组歌曲搜索。对于 songSearches 中的每个 songSearch,都会请求搜索这些歌曲并将其添加到我拥有的包含曲目的 spotify ID 的歌曲数组中。我一次需要所有这些 ID,这样我就可以执行一个 POST 请求,将所有这些曲目添加到播放列表中。因此,必须在发出 POST 请求之前完成所有搜索请求。

所有这一切都需要点击一个按钮。

点击按钮时执行的代码:

onSubmit(){
  while (this.songsService.songSearches.length){
    this.spotifyserv.searchTrack(this.songsService.songSearches[0]);
    this.songsService.songSearches.shift();
  }
  this.spotifyserv.add_tracks_to_playlist(); //Needs to wait until all requests ^ have been completed
}

搜索曲目功能:

searchTrack(searchParams: SongSearchParams, type='track'){
  var headers = new Headers({'Authorization': 'Bearer ' + this.hash_params.access_token});
  this.user_url = "https://api.spotify.com/v1/search?query="+searchParams.artist+' '+searchParams.title+"&offset=0&limit=1&type="+type+"&market=US";
  return this.http.get(this.user_url, {headers : headers})
    .subscribe(
      response => {
              var res = response.json();
              var searched_song = {artist : null, title : null, imagePath : null, spotifyID : null}
              searched_song.artist = res.tracks.items[0].artists[0].name;
              searched_song.title = res.tracks.items[0].name;
              searched_song.imagePath = res.tracks.items[0].album.images[0].url;
              searched_song.spotifyID = res.tracks.items[0].id;
              this.songsService.addSong(searched_song);
      }
    );
}

将曲目添加到播放列表功能

add_tracks_to_playlist(){
  var headers = new Headers({'Authorization': 'Bearer ' + this.hash_params.access_token});
  headers.append('Accept', 'application/json');
  this.user_url = "https://api.spotify.com/v1/users/" + this.user_id + "/playlists/" + this.playlist_id + "/tracks"; 
  let songs: Song[] = this.songsService.getSongs(); //playlist_id is hardcoded rn. needs to be added dynamically
  let songIDs : String [] = [];
  for (var i = 0; i < songs.length; i++){
    songIDs.push("spotify:track:" + songs[i].spotifyID);
  }
  let body = {"uris": songIDs};
  this.http
      .post(this.user_url, JSON.stringify(body), {headers : headers})
      .toPromise()
      .then(response => console.log(response))
      .catch(this.handleError);
}

我知道我可能想在某个地方使用 Promise.all() 但我不确定 how/where 是否使用它

正如您提到的,如果 searchTrack() returns a PromisePromise.all() 可以帮助您。所以像这样:

searchTrack(searchParams: SongSearchParams, type='track') {
  // ...
  return this.http.get(this.user_url, {headers : headers})
    .toPromise()
    .then(response => {
       // Code from your subscribe
    });
}

并更改 onSubmit

onSubmit(){
  const searchPromises: Promise<void>[] = [];
  while (this.songsService.songSearches.length){
    searchPromises.push(this.spotifyserv.searchTrack(this.songsService.songSearches[0]));
    this.songsService.songSearches.shift();
  }
  //Needs to wait until all requests ^ have been completed
  Promise.all(searchPromises)
    .then(() => this.spotifyserv.add_tracks_to_playlist());
}