android - 在 RxJava 中将 Singles 链接在一起

标签 android promise rx-java chain

我在我的 android 应用程序中使用 RxJava 以及 Retrofit 来向服务器发出网络请求。我正在使用 RxJavaCallAdapterFactory,所以我可以让我的改造请求返回单打。在我的代码中, retrofit 对象被命名为“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 请求的主体参数。需要 UserId 作为路径参数。

我在这里的主要问题是,是否有一种方法可以在没有您在此处看到的“回调 hell ”的情况下链接这些操作。就像我说的,这段代码有效,但它真的很难看。如果有人能为此指出正确的方向,我将不胜感激。有没有办法让这项工作像 promise 一样,您可以在其中链接 .thens?

谢谢。

最佳答案

代替:

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 链接一样链接平面图(和 map )。


请注意,您可以用 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) }

关于android - 在 RxJava 中将 Singles 链接在一起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42105782/

相关文章:

android - 添加/删除方法在 onCreate 中起作用,但在 onPageSelected 中不起作用

node.js - 我如何 stub Promise 以便我的测试可以同步运行?

javascript - 无法理解 Promise then 并捕获行为

android - 如何模拟采用回调对象和调用者使用回调委托(delegate)结果的方法

java - Observable-订阅两种方法

javascript - 在移动设备上,如何获取 "enter"以在类型 ="number"输入中提交表单?

android - fragment 中的 ViewBinding 属性是否应该始终具有支持的不可为空的属性?

android - Android 上使用 Flash 的增强现实应用程序

promise - Sequelize 检查行是否存在,并返回 bool 值

java - 使用 flatMap 和过滤器过滤可观察对象是否正确?