我是RxJava2的新手。
我有下一个代码:
fun signIn(): Completable = getCredentials() // get saved token
.onErrorResumeNext { makeLockSignInRequest() } // if token not saved then get it
.flatMap { refreshToken(it) } // refresh token
.doOnSuccess { credentialsManager.saveCredentials(it) } // save updated token
.doFinally { lock?.onDestroy(context) }!!
.toCompletable()
private fun getCredentials() = Single.create(SingleOnSubscribe<Credentials> {
credentialsManager.getCredentials(object : BaseCallback<Credentials, CredentialsManagerException> {
override fun onSuccess(payload: Credentials?) = it.onSuccess(payload!!)
override fun onFailure(error: CredentialsManagerException?) = it.onError(error!!)
})
})
private fun makeLockSignInRequest() = Single.create(SingleOnSubscribe<Credentials> {
lock = Lock.newBuilder(auth0, object : AuthenticationCallback() {
override fun onAuthentication(credentials: Credentials?) = it.onSuccess(credentials!!)
override fun onCanceled() { }
override fun onError(error: LockException?) = it.onError(error!!)
})
.withScheme("demo")
.withScope("email openid offline_access")
.withAudience(ApiServiceProvider.DOMAIN + "/api/")
.closable(true)
.build(context)
context.startActivity(lock!!.newIntent(context))
})
private fun refreshToken(storedCredentials: Credentials) = Single.create(SingleOnSubscribe<Credentials> {
apiClient.renewAuth(storedCredentials.refreshToken!!)
.addParameter("scope", "openid email offline_access")
.start(object : BaseCallback<Credentials, AuthenticationException> {
override fun onSuccess(receivedCredentials: Credentials?) {
val newCredentials = Credentials(receivedCredentials!!.idToken, receivedCredentials.accessToken, receivedCredentials.type, storedCredentials.refreshToken, receivedCredentials.expiresAt, receivedCredentials.scope)
it.onSuccess(newCredentials)
}
override fun onFailure(error: AuthenticationException?) {
it.onError(Exception("Error refresh token: ${error!!.description!!}"))
}
})
})
此代码将保存令牌并刷新。 同样,如果用户刚刚登录,则刷新令牌。
我想添加过滤器,如下所示:
fun signIn(): Completable = getCredentials()
.onErrorResumeNext { makeLockSignInRequest() }
.filter { OffsetDateTime.now(ZoneOffset.UTC).toEpochSecond() > it.expiresAt!!.time } // if token alive then do nothing
.flatMapSingle { refreshToken(it) }
.doOnSuccess { credentialsManager.saveCredentials(it) }
.doFinally { lock?.onDestroy(context) }!!
.toCompletable()
此代码将因错误而失败:NoSuchElementException 那么如何过滤令牌?
答案 0 :(得分:2)
.filter
将您的Single
更改为Maybe
。如果在使用Maybe
进行转换后,flatMapSingle
中没有任何项目(因为不满足过滤器要求),您的代码将返回错误,并带有NoSuchElementException
异常。
我要用的是:
fun signIn(): Completable = getCredentials()
.onErrorResumeNext { makeLockSignInRequest() }
.filter { OffsetDateTime.now(ZoneOffset.UTC).toEpochSecond() > it.expiresAt!!.time } // if token alive then do nothing
.flatMapCompletable { refreshToken(it).doAfterSuccess{credentialsManager.saveCredentials(it)}.toCompletable() }
.doFinally { lock?.onDestroy(context) }!!