Rxjava2.x 使用強大的操作符來處理巢狀請求
阿新 • • 發佈:2019-01-07
最近遇到一個需求,大概內容如下:
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你們可以請你們後臺加一個特殊欄位來識別 兩個介面返回的時候都該有相同的欄位 這樣就好處理了。