我在" A层和#34;中有两种反应方法。它暴露在应用程序中:
LAYER A - 应用程序其余部分可公开访问的方法
public Single<ResponseData> postMyData(ReqData data, Long id) {
if (!isUserLoggedIn()) return postLogin().andThen(postData(data, id));
return postData(data, id);
}
public Completable postLogin() {
Account account = getAccountData();
ReqLoginData loginData = new ReqLoginData(account.email, account.pass, OAUTH_CLIENT_ID, OAUTH_CLIENT_SECRET);
Single<ResponseLogin> singlePostLogin = postLogin(loginData);
return Completable.create(subscriber -> singlePostLogin.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(loginResponse -> {
// Success
storeAccessToken(loginResponse);// *** this will recreate apiClient with new access token
if (!subscriber.isDisposed()) subscriber.onComplete();
}, throwable -> { if (!subscriber.isDisposed()) subscriber.onError(throwable);}
));
}
LAYER B - 只能通过第A层访问
public Single<ResponseLogin> postLogin(ReqLoginData loginData) {
Log.d(TAG, "using apiClient "+apiClient.toString());
Single<Response<ResponseLogin>> postLogin = apiClient.postLogin(loginData);
return Single.create(subscriber -> postLogin.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
.subscribe(response -> {
if(response.body() != null) {
if (!subscriber.isDisposed()) subscriber.onSuccess(response.body());
} else {
if (!subscriber.isDisposed()) subscriber.onError(new Throwable(response.message()));
}
}, throwable -> {
throwable.printStackTrace();
if(!subscriber.isDisposed()) subscriber.onError(throwable);
}));
}
public Single<ResponseData> postData(ReqData data, Long id) {
Log.d(TAG, "using apiClient "+apiClient.toString());
Single<Response<ResponseData>> postData = apiClient.postData(id, data);
return Single.create(subscriber -> postData.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
.subscribe(response -> {
if(response.body() != null) {
if (!subscriber.isDisposed()) subscriber.onSuccess(response.body());
} else {
if (!subscriber.isDisposed()) subscriber.onError(new Throwable(response.message()));
}
}, throwable -> {
throwable.printStackTrace();
if(!subscriber.isDisposed()) subscriber.onError(throwable);
}));
}
LAYER C - API接口
@Headers({"Content-Type: application/json"})
@POST(Constants.API_PREFIX + "/auth/token/")
Single<Response<ResponseLogin>> postLogin(@Body ReqLoginData reqLoginData);
@Headers({"Content-Type: application/json"})
@POST(Constants.API_PREFIX + "/data/{id}/")
Single<Response<ResponseData>> postData(@Path("id") Long id, @Body ReqData reqData);
目前我面临的一个巨大挑战是确保用户在尝试POST数据之前已登录。因此,使用postLogin().andThen(postData(data, id))
对我有意义:
在我深夜开发时,似乎并行调用postLogin()
和postData()
两种方法 - 首先使用postLogin()
。
如何让postMyData()
先执行postLogin()
,等待成功或失败,然后成功postData()
?
注意: postLogin()将使用storeAccessToken()中的新令牌更新apiClient
。我现在看到postData()没有使用对新apiClient
的引用。 postData()将使用在storeAccessToken()
apiClient
非常重要
抱歉新手问题: - (
答案 0 :(得分:0)
原来,Completable.andThen(Single)
非常适合序列化代码执行。不幸的是,我没有(半睡半醒)意识到只有create()
方法中的代码才被实际安排。
下面我的代码解答了我遇到的问题(这些都在 LAYER-B 中):
public Single<ResponseLogin> postLogin(ReqLoginData loginData) {
return Single.create(subscriber -> {
Log.d(TAG, "using apiClient "+apiClient.toString());
apiClient.postLogin(loginData)
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
.subscribe(response -> {
if(response.isSuccessful() && response.body() != null) {
if (!subscriber.isDisposed()) subscriber.onSuccess(response.body());
} else {
if (!subscriber.isDisposed()) subscriber.onError(new Throwable(response.message()));
}
}, throwable -> {
throwable.printStackTrace();
if(!subscriber.isDisposed()) subscriber.onError(throwable);
});
});
}
public Single<ResponseData> postData(ReqData data, Long id) {
return Single.create(subscriber -> {
Log.d(TAG, "using apiClient "+apiClient.toString());
apiClient.postData(id, data)
.subscribeOn(Schedulers.io())
.observeOn(Schedulers.io())
.subscribe(response -> {
if(response.body() != null) {
if (!subscriber.isDisposed()) subscriber.onSuccess(response.body());
} else {
if (!subscriber.isDisposed()) subscriber.onError(new Throwable(response.message()));
}
}, throwable -> {
throwable.printStackTrace();
if(!subscriber.isDisposed()) subscriber.onError(throwable);
});
});
}