AndroidアプリでRetroxと一緒にRxJavaを使用して、サーバーにネットワークリクエストを送信しています。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が必要です。
ここでの私の主な質問は、ここに表示される「コールバック地獄」なしでこれらの操作をチェーンする方法があるかどうかです。私が言ったように、このコードは機能しますが、それは本当に醜いです。これに関して誰かが私を正しい方向に向けてくれれば幸いです。あなたが.thensをチェーンすることができるpromiseのようにこれを機能させる方法はありますか?
ありがとうございました。
の代わりに:
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));
}
});
実際には、プロミスでチェーンするようにフラットマップ(およびマップ)をチェーンできます。
2番目のフラットマップをmapに置き換えることができます。
return Single.just(new Playlist(data));
と:
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) }