最近遇到一個需求,大概內容如下:
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你們可以請你們后臺加一個特殊字段來識別 兩個接口返回的時候都該有相同的字段 這樣就好處理了。