仅在收到第二个Observable后才发出Observable

时间:2016-07-18 02:31:47

标签: android rx-java retrofit2

我使用Rx通过Retrofit调用我们的API。在某些时候,我需要调用我们的API,等待响应1,从中提取一些元数据,然后再次调用API等待响应2.在我有响应2后,我可以发出我的Observable。我的问题是,我不知道如何: 拨打电话2,只有在我有响应2后才发出

以下是应该发出Model Observable的类中的函数。方法get2不必对外界可见。

public Observable<Model> get1(String slug) {
    return api1
            .getInfo(slug)
            .subscribeOn(Schedulers.io())
            .map(resonse1 -> {
                String metadata = response1.getMetadata();

                //Make call2 with metadata
                //call(2)

                Model model = response1.getModel();
                model.setInfo(/*Info from call2*/) 

                return model;
            })
            .observeOn(AndroidSchedulers.mainThread());
}


private Observable<Info> get2(String metadata) {
    return api2.getInfo(new InfoAsset(metadata))
            .subscribeOn(Schedulers.io())
            .map(response2 -> {
                return response2.getInfo;
            })
            .observeOn(AndroidSchedulers.mainThread());
}

2 个答案:

答案 0 :(得分:2)

而不是map使用flatMap

.flatMap(response1 -> {
            String metadata = response1.getMetadata();
            return get2(metadata)
              .map(info -> {
                     Model model = response1.getModel();
                     model.setInfo(info); 
                     return model;
                   });
         })
...

请注意,因为您在跨线程使用可变对象,因此可能存在可见性问题。考虑使用不可变对象或确保更改已同步。

答案 1 :(得分:1)

使用嵌套的flatMaps,除非你想跳线,否则不要使用observeOn:

private Observable<Info> get2(String metadata) {
    return api2.getInfo(new InfoAsset(metadata))
        .subscribeOn(Schedulers.io())
        .map(response2 -> {
            return response2.getInfo;
        });
        // no ObserveOn here.
} 

public Observable<Model> get1(String slug) {
    return api1
        .getInfo(slug)
        .subscribeOn(Schedulers.io())
        .flatMap (response1 -> {
            Model model = response1.getModel();
            return get2(response1.getMetadata())
                   .map(response2 -> {
                        model.setInfo(response2); 
                        return model;
                   });
        );
    });
}