探索可观察对象,我遇到了一个问题,我需要在另一个函数完成后才执行函数。所有功能都是使用Http
中的@angular/http
服务的异步操作。
调用链应该是
GET
推荐曲目通常情况下,我会用承诺书写这个,并且链条看起来像
this.checkIfPlaylistExists()
.then((exists) => {
if(!exists) {
return this.createPlaylist();
}
})
.then(() => this.getRecommendedTracks(seedTracks)) //resolves tracks
.then(this.addRecommendedTracksToPlaylist)
.then(doSomethingElse)
.catch();
我的困惑是如何使用observable编写代码。到目前为止,我没有100%工作,看起来像这样
createRecommendedTracksPlaylist(seedTracks: Track[]) {
this.checkIfPlaylistExists()
.map(exists => {
if (!exists) {
return this.createPlaylist();
}
})
.map(() => this.getRecommendedTracks(seedTracks))
.map((tracks) => this.addRecommendedTracksToPlaylist(tracks)) //<--- if I comment out this line, 'getRecommendedTracks' is executed and prints out response
.mergeAll()
.subscribe();
}
名为
的函数getRecommendedTracks(seedTracks: Track[]) {
seedTrackIds = seedTracks.map((track) => track.id).join(',');
const recommendationsUrl = `https://api.spotify.com/v1/recommendations?seed_tracks=${seedTrackIds}`;
return this.http.get(recommendationsUrl, options).map((res) => {
const recommendedTracks = res.json().tracks as Array<Track>;
console.log('Getting recommended tracks'); //Is only run if I don't run 'addRecommendedTracksToPlaylist' function
console.log(recommendedTracks);
return recommendedTracks;
});
}
addRecommendedTracksToPlaylist(tracksToAdd) {
console.log('Going to add tracks..');
console.log(tracksToAdd); //Prints out 'Observable {_isScalar: false, ... }'
const options = this.getAuthHeader();
const playlistUri = '2OGx5l1ItjzMsQdQ0Hec6g';
const addTracksUrl = `https://api.spotify.com/v1/users/${this.userId}/playlists/${playlistUri}/tracks`;
return this.http.get(addTracksUrl, options);
}
修改:添加checkIfPlaylistExists
代码(请注意,目前该播放列表始终存在)
private checkIfPlaylistExists() {
const options = this.getAuthHeader();
const playlistUrl = `https://api.spotify.com/v1/users/${this.userId}/playlists`;
return this.http.get(playlistUrl, options).map((res) => {
const playlists = res.json().items as Array<any>;
return playlists.some((e, i, a) => {
return e.name.indexOf(this.playlistTitle) > -1;
})
});
}
总结一下
getRecommendedTracks
在&#39;链中运行,为什么功能addRecommendedTracksToPlaylist
才会执行?Observable.map
功能?我所看到的所有示例都将它用于单个对象和数组,但我不确定我是否正确使用它。答案 0 :(得分:2)
只需将您的.map()
更改为.flatMap()
,就可以了:
createRecommendedTracksPlaylist(seedTracks: Track[]) {
this.checkIfPlaylistExists()
.flatMap(exists => {
if (!exists) {
return this.createPlaylist();
}
return Observable.of(1);
})
.flatMap(() => this.getRecommendedTracks(seedTracks))
.flatMap((tracks) => this.addRecommendedTracksToPlaylist(tracks))
.subscribe();
}
如果playlist
不存在,则需要返回一个虚拟Observable,因为flatMap期望返回Observable。 Observable.empty()
因为刚结束流而无法工作。