背景
挪动app中展现的数据少数都是通过服务器接口获取的,当接口数据与用户相干时,服务端接口会要求客户端把用户信息通过接口发送到服务器。广泛的做法是把用户登录后的token数据发送给服务器的接口。思考到平安问题,token都有过期工夫,token过期后服务端就不能通过这个token查问用户的具体信息了。为了刷新过期token,服务端会提供一个刷新token的接口给客户端应用。
问题剖析
因为要求上传token的服务端接口会有很多,所以这些接口的调用都须要思考token过期生效问题。
这些接口调用的异样解决中须要减少token过期解决,在token过期的状况下触发token刷新解决。
token刷新后触发接口的重试申请。
如何应用flow实现
首先咱们实现一个刷新token的flow。
private val refreshTokenFlow = flow { if (expiredToken) { cachedToken = serverApi.refreshToken("token-0") expiredToken = false } emit(cachedToken) }
expiredToken变量代表token是否过期,理论开发过程中这个变量的值应该依据过期工夫计算得出的。cachedToken变量保留着最新的token值,申请用户相干信息的接口时能够把这个token传递给服务端用于查问。咱们能够看到cachedToken的值是通过调用服务端提供的刷新接口获取的。这个flow最终发射的是最新的token值,同时咱们也看到这个flow调用刷新接口的逻辑只有token过期时才会被调用。
第二步定义申请用户相干数据的flow
private fun getDataFlow(token: String) = flow { emit(serverApi.getDataViaToken(token)) }
因为申请用户数据的接口依赖token的值,所以这个flow是通过办法生成的。flow的生成也比较简单,它间接调用服务端的接口并将数据发射进来。
第三步将刷新token的flow和申请用户数据的flow开展
private val userDataFlow = refreshTokenFlow.flatMapConcat{token-> getDataFlow(token) }
flatMapConcat办法将后面定义的两个流拼接在一起,这时咱们要是收集拼接后的userDataFlow,refreshTokenFlow会被收集,flatMapConcat办法接管到 refreshTokenFlow发射的token后开始收集getDataFlow办法返回的flow。这样连个flow的依赖关系通过flatMapConcat完满实现了。
第四步实现token过期重试机制
private val userDataFlow = refreshTokenFlow.flatMapConcat{token-> getDataFlow(token) }.retryWhen { cause, attempt -> if (attempt > 1) { false } else if(cause is InvalidTokenException) { expiredToken = true true }else{ false } }.catch { msgView.text = it.message }
基于第三步的flow拼接咱们增加了retryWhen和cach两个块。retryWhen块用于实现重试机制,参数cause是后面流程产生的异样,参数attempt代表重试的次数,返回值true代表进行重试,返回值false代表不进行重试。在retryWhen块中咱们能够通过cause的类型来判断是否要重试,当cause为InvalidTokenException时代表token过期,所以进行重试并且重置了token过期expiredToken。为了防止有限地进行重试,这里限度重试次数为一次。catch块解决不进行重试时的逻辑,个别会将出错的信息显示到界面上。
总结
通过flow的形式实现token刷新机制相较于传统的形式有如下劣势:
逻辑简单明了,刷新流程简略清晰直观。flow操作符语义简单明了,链式的形式申明处理过程更容易了解,没有简单的嵌套。
通过申明的形式定义了刷新流程,同时也反对通过申明的形式扩大已有流程。比方这里拼接了刷新token的flow和获取用户数据的flow。
重试机制能够依据不同的依赖token接口进行定制解决,接口的重试机制更加灵便不便。这里没有针对重试流程定义新的flow,但在理论利用中咱们能够为重试流程定义flow,而后将flow拼接在已有flow后。这样咱们能够在不同的中央重用重试流程的flow。
我的公众号曾经开明,公众号会同步公布。
欢送关注我的公众号
————————————————
版权申明:本文为CSDN博主「mjlong123123」的原创文章,遵循CC 4.0 BY-SA版权协定,转载请附上原文出处链接及本申明。
原文链接:https://blog.csdn.net/mjlong1...