Skip to content

Instantly share code, notes, and snippets.

@walkingice
Last active December 1, 2016 14:24
Show Gist options
  • Save walkingice/32cd8dd29f5169250c93c9ae09af5d3f to your computer and use it in GitHub Desktop.
Save walkingice/32cd8dd29f5169250c93c9ae09af5d3f to your computer and use it in GitHub Desktop.
Two dependent API calls without using POJO
package learning;
import rx.Observable;
import rx.Subscriber;
import java.util.concurrent.CountDownLatch;
/**
* Q: 對於數個 API call,能否不透過 POJO,仍然以一個 chain 就拿到 server 回傳的結果?
* 假設有三個 API 1) getToken 2) getFirstData 3) getSecondData
* getToken 會回傳一個字串,是為 token;getFirstData 需要以該 token 為參數來呼叫
* 而 getSecondData,不但需要 token,還需要 getFirstData 的回傳值
*
* 以現實情況的比喻,就是欲取得同學的身高體重(getSecondData),還需要先取得所有同學的 id (getFirstData)
*
* 目前想不到連成一個 chain 的方法,而是分開來用 zip 與 concat 組合起來避開使用 POJO
*/
public class Main {
public Observable loadData() {
Observable<String> tokens = MockApi.getToken().repeat(2);
Observable<String> firstCall = tokens.take(1)
.flatMap(token -> MockApi.getFirstData(token));
// actually we only have one call
Observable<Observable<String>> calls = Observable.zip(tokens.first(),
firstCall,
(token, firstResp) -> MockApi.getSecondData(token, firstResp));
return Observable.concat(calls);
}
public void wrapper() throws InterruptedException {
final CountDownLatch latch = new CountDownLatch(1);
Observable ob = loadData();
ob.subscribe(new Subscriber() {
@Override
public void onCompleted() {
latch.countDown();
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
}
@Override
public void onNext(Object o) {
System.out.println(o);
}
});
latch.await();
}
public static void main(String[] args) {
System.out.println("------- start -------");
Main m = new Main();
try {
m.wrapper();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("------- end -------");
}
static class MockApi {
public static Observable<String> getToken() {
System.out.println("Get Token invoked");
return Observable.just("Access_token").delay(300, TimeUnit.MILLISECONDS);
}
public static Observable<String> getFirstData(String token) {
System.out.println("Get First Data invoked");
return Observable.just(token + " is used in getFirstData").delay(300, TimeUnit.MILLISECONDS);
}
public static Observable<String> getSecondData(String token, String lastResult) {
System.out.println("Get Second Data invoked");
return Observable.just(token + " is used in getSecondData, last is:" + lastResult)
.delay(300, TimeUnit.MILLISECONDS);
}
}
}
@kojilin
Copy link

kojilin commented Dec 1, 2016

不夠深的話可以這樣?

MockApi.getToken().repeat(2).flatMap(token -> {
            return MockApi.getFirstData(token)
                          .flatMap(firstResp -> MockApi.getSecondData(token, firstResp));
        });

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment