Lambda 新单后错误

Lambda 新单后错误,lambda,oauth-2.0,rx-java2,Lambda,Oauth 2.0,Rx Java2,我开发了自己的下载用户数据流,但遇到了问题。先买一些代码,方法说明: loginManager.getAccessToken() //Returns Single<String> where string is my access token loginManager.getRefreshToken() //Returns Single<String> where string is my refresh token loginManager.downloadUserAc

我开发了自己的下载用户数据流,但遇到了问题。先买一些代码,方法说明:

loginManager.getAccessToken() //Returns Single<String> where string is my access token
loginManager.getRefreshToken() //Returns Single<String> where string is my refresh token
loginManager.downloadUserAccountData(String accessToken) //Returns Single<String> where string is my json response
loginManager.refreshAccessToken(String refreshToken) //Returns Single<String> where string is new access token
userManager.parseUserJson(String json) //Returns Single<User> where User is my user model
userManager.storeUser(User user) //Returns Completable
但这不支持刷新访问令牌并重试下载。当我的accessToken不是当前的时,服务器抛出403,所以在这种情况下,我在函数downloadUserAccountData中返回错误

现在我尝试使用doError和onErrorReturn,但这两个操作符都不符合我的要求。这是因为DoError只允许显示日志,不返回任何内容。onErrorReturn允许我只返回一个值,而不是一个值

这是我试图实现的伪代码:

Completable getAndStoreUserData = loginManager.getAccessToken()
        .flatMap(loginManager::downloadUserAccountData)
        .onErrorReturn(error -> loginManager.getRefreshToken()
                .flatMap(loginManager::refreshAccessToken)
                .flatMap(loginManager::downloadUserAccountData)
        .flatMap(userManager::parseUserJson)
        .flatMapCompletable(userManager::storeUser);
欣赏任何示例:

也许您可以使用retryWhen

返回与源ObservableSource发出相同值的Observable,但onError除外。来自源的onError通知将导致向作为notificationHandler函数参数提供的ObservableSource发出可丢弃项。如果该ObservableSource调用onComplete或onError,则retry将对子订阅调用onComplete或onError。否则,此ObservableSource将重新订阅源ObservableSource

其他一些例子


对不起,我的英语不好,我对lambda不熟悉。

我终于学会了,怎么做。正如@Cochi所提议的,我使用了retryWhen函数。这是一个非常简单的基于字符串的示例:

String body = null;

@Override
protected void onStart() {
    super.onStart();

    Single<String> stringSingle = Single.create(source -> {
                if(body != null) {
                    source.onSuccess(body);
                }
                else {
                    source.onError(new Exception("403"));
                }
            })
            .retryWhen(errors -> errors.flatMap(error -> {
                if(error.getMessage().contains("403")) {
                    Throwable throwable = refresh().blockingGet();
                    if(throwable == null) {
                        return Flowable.just(new Object());
                    }
                    return Flowable.error(throwable);
                }
                return Flowable.error(error);
            }))
            .flatMap(obj -> Single.just(obj.toString()));
}

public Completable refresh() {
    return Completable.create(source -> {
        try {
            body = "Success";
            source.onComplete();
        }
        catch (Exception e) {
            source.onError(e);
        }
    });
}
还有一个完整的示例,使用我的代码:

Completable getAndStoreUserData() {}
    Completable getAndStoreUserData = loginManager.getAccessToken()
            .flatMap(loginManager::downloadUserAccountData)
            .retryWhen(errors -> errors.flatmap(this::retryConditionChecker))
            .flatMapCompletable(userManager::storeUser);

    return getAndStoreUserData
}

Publisher<?> retryConditionChecker(Throwable error) {
    if(error.getMessage().contains("403")) {

        Throwable throwable = loginManager.getRefreshToken()
                .flatMap(loginManager::refreshAccessToken)
                .flatMapCompletable(loginManager::replaceAccessToken)
                .blockingGet();

        if(throwable == null) {
            return Flowable.just(new Object());
        }
        return Flowable.error(throwable);
    }
    return Flowable.error(error);
}

但最大的问题是封锁。我认为这是一个非常糟糕的解决方案。也许有人知道更好的吗

你用改装吗?@Cochi不,我不用。我不能在这个项目中使用改型:你能提供一个简单的例子,即使是在字符串上操作,这代表了我的问题吗?目前我不知道如何使用它。是的,我会试试。
String body = null;

@Override
protected void onStart() {
    super.onStart();

    Single<String> stringSingle = Single.create(source -> {
                if(body != null) {
                    source.onSuccess(body);
                }
                else {
                    source.onError(new Exception("403"));
                }
            })
            .retryWhen(errors -> errors.flatMap(error -> {
                if(error.getMessage().contains("403")) {
                    Throwable throwable = refresh().blockingGet();
                    if(throwable == null) {
                        return Flowable.just(new Object());
                    }
                    return Flowable.error(throwable);
                }
                return Flowable.error(error);
            }))
            .flatMap(obj -> Single.just(obj.toString()));
}

public Completable refresh() {
    return Completable.create(source -> {
        try {
            body = "Success";
            source.onComplete();
        }
        catch (Exception e) {
            source.onError(e);
        }
    });
}
Completable getAndStoreUserData() {}
    Completable getAndStoreUserData = loginManager.getAccessToken()
            .flatMap(loginManager::downloadUserAccountData)
            .retryWhen(errors -> errors.flatmap(this::retryConditionChecker))
            .flatMapCompletable(userManager::storeUser);

    return getAndStoreUserData
}

Publisher<?> retryConditionChecker(Throwable error) {
    if(error.getMessage().contains("403")) {

        Throwable throwable = loginManager.getRefreshToken()
                .flatMap(loginManager::refreshAccessToken)
                .flatMapCompletable(loginManager::replaceAccessToken)
                .blockingGet();

        if(throwable == null) {
            return Flowable.just(new Object());
        }
        return Flowable.error(throwable);
    }
    return Flowable.error(error);
}