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