在我的应用程序中,所有请求都需要一个令牌作为http授权标头,该标头在一段时间后过期。当一个作业从服务器获取401
状态代码时,我需要启动作业来刷新令牌。完成此工作后,我需要通知我的应用程序中的所有作业,因为我不知道哪些作业失败(作业已完成但是有401状态),我必须使用新令牌重试它。
如何使用协同程序执行此操作?
首先,让我们定义令牌的刷新方式:
1)如果还没有刷新令牌的请求,请启动一个新令牌
2)如果有一个已经发生,请等待。
在Kotlin中可以写成:
var retrieveToken : Deferred<String>? = null
suspend fun getToken(refresh: Boolean = false): String {
if(retrieveToken == null || refresh && !retrieveToken.isActive)
retrieveToken = async { API.getToken() }
return retrieveToken.await()
}
现在重试API变得非常简单:
suspend fun requestAPIAndRetry(api: String) {
try {
val token = getToken()
val result = API.call(api, token)
} catch(error) {
// verifiy if it is 401
val token = getToken(refresh = true)
var result = API.call(api, token)
}
}
现在,如果请求开始失败,则会发生以下情况:
1)对getToken(refresh = true)
的第一次调用将启动对API的请求并将返回该请求。
2)所有后续调用将与第一次调用一样延迟,因此所有请求只等待一次令牌更新
3)如果令牌在那里,Deferred将解析,并且所有API将重试(甚至可以并行)。