用RX和Kotlin编写网络请求

时间:2015-07-09 13:44:41

标签: android system.reactive retrofit rx-java kotlin

我正在开发一个Android应用程序,它使用带有RXJava和Retrofit的kotlin进行网络调用。启动时,应用程序将对类似REST的后端进行多次网络调用。该过程看起来非常类似于Netflix在其示例中使用的过程。然而,当试图重写它与Kotlin一起工作时,我正在努力。我很难理解返回在Kotlin闭包中是如何工作的。非常感谢这里的一些帮助!

Netflix示例:

    return getUser(userId).flatMap(user -> {
        Observable<Map<String, Object>> catalog =    getPersonalizedCatalog(user)
            .flatMap(catalogList -> catalogList.videos().<Map<String, Object>> flatMap(
                    video -> {
                        Observable<Bookmark> bookmark = getBookmark(video);
                        Observable<Rating> rating = getRatings(video);
                        Observable<VideoMetadata> metadata = getVideoMetadata(video);
                        return Observable.zip(bookmark, rating, metadata, (b, r, m) -> combineVideoData(video, b, r, m));
                    }));

    Observable<Map<String, Object>> social = getSocial(user).map(s -> {
        return s.getDataAsMap();
    });

    return Observable.merge(catalog, social);
}).flatMap(data -> {
    String json = SimpleJson.mapToJson(data);
    return response.writeStringAndFlush("data: " + json + "\n");
});

我的解决方案:

restClient.getVideoList("VAR1", "VAR2")
                .subscribeOn(Schedulers.io())
                .flatMap { videos -> Observable.from(videos)}
                .map { video ->
                    var actors: Observable<List<Actor>> = restClient.getActorList(video.id(), "VAR2")
                    var price = restClient.getPrice(video.id(), "VAR2")
                    Observable.zip(actors, price, { (a, p) ->  combineVideoData(video, a, p)})
                }.map{ video -> doSomethingWithVideo(video) }

出于某种原因,我的实现返回了一个observable而不是它应该是的视频对象。毫无疑问,我对Kotlin关闭的理解有些不对劲,我试图弄清楚它已经好几天了,但仍然在苦苦挣扎。非常感谢任何帮助!

2 个答案:

答案 0 :(得分:1)

您已创建了可观察但未订阅的内容。您应该使用forEach {}(来自RxKotlin)或subscribe {}而不是最后map。它看起来像

restClient.getVideoList("VAR1", "VAR2")
                .subscribeOn(Schedulers.io())
                .flatMap { videos -> Observable.from(videos)}
                .map { video ->
                    var actors: Observable<List<Actor>> = restClient.getActorList(video.id(), "VAR2")
                    var price = restClient.getPrice(video.id(), "VAR2")
                    Observable.zip(actors, price, { (a, p) ->  combineVideoData(video, a, p)})
                }.forEach { video -> doSomethingWithVideo(video) }

答案 1 :(得分:0)

当你操纵一个可观察者时,你会得到一个新的可观察者。

如果你想从你的观察中获得你的价值,你必须通过阻止它来退出它(&#34;退出monad&#34;):

val value = yourObs.toBlocking().first()