我在我的Android应用程序中使用RxJava和Retrofit向服务器发出网络请求。我正在使用RxJavaCallAdapterFactory,所以我可以让我的改装请求返回单打。在我的代码中,改造对象被命名为' api'。
此处的代码运行正常,但在此示例中,我需要在创建播放列表之前检索userId。我将userId请求平面映射到API请求,在制作播放列表后,我需要再次使用平面地图将JSON响应转换为可用对象。
public JSONUser me;
public Single<String> getUserId(){
if(me != null){
return Single.just(me.getUserId());
}
return api.getMe().flatMap(new Func1<JSONUser, Single<String>>() {
@Override
public Single<String> call(JSONUser meResult) {
me = meResult;
return Single.just(me.getUserId());
}
});
}
public Single<Playlist> createPlaylist(String name) {
final NewPlaylistConfig config = new NewPlaylistConfig(name);
return getUserId().flatMap(new Func1<String, Single<Playlist>>() {
@Override
public Single<Playlist> call(String userId) {
return api.createPlaylist(userId, config).flatMap(
new Func1<JSONPlaylist, Single<? extends SpotifyPlaylist>>() {
@Override
public Single<? extends Playlist> call(JSONPlaylist data) {
return Single.just(new Playlist(data));
}
});
}
});
}
这里的入口点是createPlaylist()。 NewPlaylistConfig将转换为JSON,并且只是POST请求的body参数。需要UserId作为路径参数。
我的主要问题是,如果有一种方法可以在没有&#34;回调 - 地狱&#34;的情况下将这些操作链接起来。你在这看到就像我说的,这段代码有效,但它真的很难看。如果有人能指出我正确的方向,我将不胜感激。有没有办法使这项工作像承诺一样,你可以链接.thens?
谢谢。
答案 0 :(得分:15)
而不是:
getUserId()
.flatMap(new Func1<String, Single<Playlist>>() {
@Override
public Single<Playlist> call(String userId) {
return api.createPlaylist(userId, config).flatMap(
new Func1<JSONPlaylist, Single<? extends SpotifyPlaylist>>() {
@Override
public Single<? extends Playlist> call(JSONPlaylist data) {
return Single.just(new Playlist(data));
}
});
}
});
写:
getUserId()
.flatMap(new Func1<String, Single<Playlist>>() {
@Override
public Single<Playlist> call(String userId) {
return api.createPlaylist(userId, config);
}
})
.flatMap(
new Func1<JSONPlaylist, Single<? extends SpotifyPlaylist>>() {
@Override
public Single<? extends Playlist> call(JSONPlaylist data) {
return Single.just(new Playlist(data));
}
});
实际上你可以像你一样使用promises链接flatmap(和map)。
请注意,您可以使用地图替换第二个flatmap,替换:
return Single.just(new Playlist(data));
with:
return new Playlist(data);
结果:
getUserId()
.flatMap(new Func1<String, Single<Playlist>>() {
@Override
public Single<Playlist> call(String userId) {
return api.createPlaylist(userId, config);
}
})
.map(
new Func1<JSONPlaylist, SpotifyPlaylist>() {
@Override
public SpotifyPlaylist call(JSONPlaylist data) {
return new Playlist(data);
}
});
编辑:你可以继续使用java 8:
getUserId()
.flatMap(userId -> api.createPlaylist(userId, config))
.map(data -> new Playlist(data));
或者Kotlin:
getUserId()
.flatMap { api.createPlaylist(it, config) }
.map { Playlist(it) }