Android 在多个异步协同路由中调用的方法如何只能调用一次?
在主屏幕上,有3个异步请求:Android 在多个异步协同路由中调用的方法如何只能调用一次?,android,kotlin,kotlin-coroutines,Android,Kotlin,Kotlin Coroutines,在主屏幕上,有3个异步请求: viewModelScope.launch { try { val requestAccountDeffer = async { requestAccounts() } val updateStatusDeffer = async { updateVerificationStatus() } val requestProfileDeffer = async { requestProfile() } requestAccountDe
viewModelScope.launch {
try {
val requestAccountDeffer = async { requestAccounts() }
val updateStatusDeffer = async { updateVerificationStatus() }
val requestProfileDeffer = async { requestProfile() }
requestAccountDeffer.await()
updateStatusDeffer.await()
requestProfileDeffer.await()
} catch (exception: Throwable) {
// ...
}
}
我的后端使用一个accessToken(过期一分钟)和一个refreshToken来更新它。在每次请求之前,都会检查accessToken是否已过期,并在必要时进行更新
问题是,如果accessToken在主屏幕开始时过期,那么更新它的方法将被调用三次(在每个异步{…}块中),并且后端在尝试更新accessToken时将返回错误。如何只进行一次asynСblock调用来更新令牌
我可以在调用异步块之前同步更新令牌,但在我看来,这并不是正确的解决方案
更新
当前accessToken和refreshToken存储在sharefPrefs中
通过使用Kotlin的异步:
接口互斥体
()
共程互斥。// 基本上,您可以锁定资源,必要时暂停,检查资源是否已过期并可能续订,然后返回当前值
private lateinit var currentToken: AccessToken
private val tokenMutex = Mutex()
suspend fun getToken(): AccessToken {
return tokenMutex.withLock {
if (currentToken.isExpired) {
// Refresh token
val newToken = ...
// Update the stored token
currentToken = newToken
newToken
} else currentToken
}
}
然后,不直接访问当前令牌值,而是将此函数用作一种get或update代理
Mutex
的功能等同于,只是它挂起而不是阻塞,并且不可重入
也就是说,我认为在发出三个请求之前更新令牌的替代方法不会有任何问题
旁注:绝对没有理由启动三个
延迟的作业并立即等待它们;这是一个非常好的用例:
此调用将挂起,直到新创建的作用域的所有子作业完成,并且在其中一个子作业引发异常时将失败
如果此行为不是您想要的,您可以改用(另请参阅),或安装自己的异常处理程序。如果我理解正确,您会担心如果访问令牌在三个请求发出之前过期,那么每个请求都会尝试独立更新访问令牌。您如何在协同程序之间共享/更新当前令牌?理想情况下,多个协同路由不可能同时更新共享资源。如果您想阻止所有请求独立访问或修改当前令牌,您可能必须将访问逻辑封装在某种并发限制机制中,例如锁(无论令牌是存储在内存中还是通过SharedReferences
存储在磁盘上,其基本思想都是相同的)
coroutineScope {
launch { requestAccounts() }
launch { updateVerificationStatus() }
launch { requestProfile() }
}