1. 程式人生 > >Rxjava2.x 使用強大的操作符來處理巢狀請求

Rxjava2.x 使用強大的操作符來處理巢狀請求

最近遇到一個需求,大概內容如下:

1、請求A介面返回物件集合(假設物件是VideoTest 有一個引數url跟引數名id);
2、需要再根據每個物件的id 請求介面B ,介面B會返回最終的url字串;
3、再把介面B返回的url設定到對應的物件上,然後最終返回所有有了正確的url引數的物件集合。

一開始聽到這個需求,我感覺很簡單 先請求介面A得到集合之後 在for迴圈一個一個請求 在設定到對應的物件上,但是這樣對於使用rxjava的人來說 真的是醜到爆!!!然後我就網上找啊找,找了半天沒找到 那就自己動手 然後我就去百度rx2.x的操作符大全 一個一個看 有沒有能適用於這個需求的,功夫不負有心人啊 。下面直接上程式碼吧

public class Test {
    private Map<Integer, VideoTest> map = new HashMap<>();
    private int index = 0;

    public void test() {
        List<VideoTest> videoTests = new ArrayList<>();

        for (int i = 0; i < 6; i++) {
            VideoTest videoTest = new VideoTest("qwert"
+ i, "http:www.dddd.com/" + i); videoTests.add(videoTest); } Observable.fromArray(videoTests)//這裡模擬請求資料集合 .flatMap(new Function<List<VideoTest>, ObservableSource<VideoTest>>() { @Override public ObservableSource<VideoTest> apply
(@NonNull List<VideoTest> pVideoTests) throws Exception { index = 0; return Observable.fromIterable(pVideoTests);// 這裡的fromIterable是一個一個傳送資料 } }) //單獨處理每個資料 .map(new Function<VideoTest, String>() { @Override public String apply(@NonNull VideoTest pVideoTest) throws Exception { //這裡需要使用map來繫結物件跟key key可以使用integer map.put(index, pVideoTest); return pVideoTest.getUrl(); } }) .map(new Function<String, String>() { @Override public String apply(@NonNull String ps) throws Exception { //這邊處理url 應該是請求介面B 我這就簡單點處理了 return ps + "處理過的"; } }) .map(new Function<String, VideoTest>() { @Override public VideoTest apply(@NonNull String pS) throws Exception { //這邊應該將正確的url賦值給對應的物件 VideoTest videoTest = map.get(index); videoTest.setUrl(pS); index++; return videoTest; } }) //這個操作符是用來收集物件的 .collect(new Callable<List<VideoTest>>() { @Override public List<VideoTest> call() throws Exception { return new ArrayList<>(); } }, new BiConsumer<List<VideoTest>, VideoTest>() { @Override public void accept(List<VideoTest> pNewses, VideoTest pNews) throws Exception { pNewses.add(pNews); } }).subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Consumer<List<VideoTest>>() { @Override public void accept(List<VideoTest> pVideoTests) throws Exception { for (VideoTest v : pVideoTests) { Logger.e("----s---d--d-d--d-d-d-d-" + v.getId() + "," + v.getUrl()); } } }, new Consumer<Throwable>() { @Override public void accept(Throwable pThrowable) throws Exception { Logger.e(pThrowable.getMessage()); } }); }

我覺得map的key你們可以請你們後臺加一個特殊欄位來識別 兩個介面返回的時候都該有相同的欄位 這樣就好處理了。