如何在不可修改的回调Builder模式下重构认证代码为Coroutine
回调风格认证代码转协程的优雅实现
不需要传入CoroutineScope作为参数,suspend函数本身就运行在协程上下文里,直接用suspendCancellableCoroutine就能优雅地把回调逻辑转换成协程风格,同时处理认证成功、失败和取消的双向同步。
改造后的核心代码
suspend fun authenticate(/* parameters */): AuthenticationResult { val builder = // 原有的builder获取逻辑保持不变 return suspendCancellableCoroutine { continuation -> val callback = object : AuthenticationCallback { override fun onSuccess(authenticationResult: AuthenticationResult) { if (continuation.isActive) { continuation.resume(authenticationResult) } } override fun onError(exception: AuthenticationException) { if (continuation.isActive) { continuation.resumeWithException(exception) } } override fun onCancel() { if (continuation.isActive) { continuation.cancel(CancellationException("认证操作被取消")) } } } // 绑定回调并构建实例 val authInstance = builder.withCallback(callback).build() // 这里根据原代码逻辑,执行启动认证的操作(比如authInstance.start()) // 处理协程主动取消的情况:如果SDK支持主动终止认证,在此调用对应方法 continuation.invokeOnCancellation { // 示例:authInstance.cancel() } } }
关键细节说明
suspendCancellableCoroutine的优势:相比suspendCoroutine,它支持协程取消的回调处理,能实现协程取消与认证流程取消的双向同步。- 检查
continuation.isActive:避免在协程已经被取消后,仍尝试恢复结果,防止出现无效操作或异常。 - 无需额外传
CoroutineScope:suspend函数只能在协程或其他suspend函数中调用,天生具备协程上下文,不需要额外传入Scope。
调用示例
在协程作用域中直接调用改造后的suspend函数,用常规的try-catch处理结果:
// 以ViewModel协程作用域为例 viewModelScope.launch { try { val authResult = authenticate(/* 传入参数 */) // 处理认证成功逻辑 } catch (e: AuthenticationException) { // 处理认证失败错误 } catch (e: CancellationException) { // 处理认证被取消的情况 } }
内容的提问来源于stack exchange,提问作者Lorenzo B
相关产品推荐
相关产品推荐

