如何顺序执行"可完成"其次是" Single"?

时间:2018-01-12 00:37:04

标签: rx-java2

我在" 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非常重要

抱歉新手问题: - (

1 个答案:

答案 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);
            });
    });
}