我有一个问题,我不知道如何用更好的方法来解决它。问题是我请求Spotify Web API,在一些方法中,艺术家图像被返回,而在另一些方法中,只获得基本的艺术家信息。
我有两种方法:
fun getAlbum(albumId: String): Single<SpotifyAlbumDTO>
fun getArtist(artistId: String): Single<SpotifyArtistDTO>当我得到一个相册时,艺术家信息不包含艺术家图像url。因此,我需要调用getAlbum()方法并使用结果来获取artistId,然后调用getArtist()方法。
我有以下方法来做所有这些事情:
fun getAlbum(albumId: String): Single<Album>在这个方法中,我需要调用前两个方法来返回一个Album对象(我的域对象)。对我来说唯一有效的解决方案是:
fun getAlbum(albumId: String): Single<Album> {
return Single.create { emitter ->
_spotifyService.getAlbum(albumId).subscribe { spotifyAlbum ->
_spotifyService.getArtist(spotifyAlbum.artist.id).subscribe { spotifyArtist ->
val artistImage = spotifyArtist.imageUrl
spotifyAlbum.artist.image = artistImage
emitter.onNext(spotifyAlbum.toAlbum())
}
}
}
}我认为肯定存在另一种更好的方法来实现这一点,而不是在其他订阅中连接订阅调用并创建更深层次的调用。我还尝试了以下几种方法:
_spotifyService.getAlbum(albumId).flatMap { spotifyAlbum ->
_spotifyService.getArtist(spotifyAlbum.artist.id)
}.flatMap { spotifyArtist ->
// Here I don't have the album and I can't to asign the image
}发布于 2020-01-13 07:26:04
并行求解
要组合多个数据源,最好的运算符是zip

Single.zip(getAlbum(albumId), getArtist(artistId),
BiFunction<SpotifyAlbumDTO, SpotifyArtistDTO, SpotifyAlbumDTO> { album, artist ->
val artistImage = artist.imageUrl
album.artist.image = artistImage
album //return value of the merged observable
}
).subscribe { album: SpotifyAlbumDTO?, error: Throwable? ->
emitter.onNext(album.toAlbum())
}它将并行运行所有可观测对象,并在每个可观测对象完成后执行合并函数。
如果你有更多可观察的压缩,你可以使用Function3,Function4,...
顺序解决方案(编辑)
如果由于您需要按顺序执行请求而无法并行执行,那么您可以使用flatmap函数的resultSelector。它在flatmap之前获取项,在平面映射之后获取分组集合。这样,您就可以轻松地创建模型组,而不会混淆Pair的用法

唯一的问题是:Single不支持这种平面映射。您可以解决此问题,或者将返回类型从Single更改为Observable,或者在运行时使用toObservable运算符转换Single。
getAlbum(albumId)
.toObservable()
.flatMap({album: SpotifyAlbumDTO -> getArtist(album.artist.id).toObservable()},
{ album:SpotifyAlbumDTO, artist:SpotifyArtistDTO ->
album.artist.image = artist.imageUrl
album
})
}?.subscribe { album: SpotifyAlbumDTO ->
print(album)
}发布于 2020-01-13 05:27:01
您可以使用带有flatMap的Pair将您的结果打包在一起:
_spotifyService.getAlbum(albumId).flatMap { spotifyAlbum ->
_spotifyService.getArtist(spotifyAlbum.artist.id)
.flatMap { artist ->
Single.just(spotifyAlbum, artist)
}
}.subscribe { pair: Pair<Album, Artist> ->
// grab results
val album = pair.first
val artist = pair.second
}https://stackoverflow.com/questions/59708108
复制相似问题