首页 > 解决方案 > 如何从协程返回错误响应

问题描述

我正在尝试将所有回调更改为协程,我已经阅读了它们并且它们很吸引人!

我想要完成的只是登录一个用户,但如果登录逻辑失败,请通知我的演示者。

这就是我所做的

LoginPresenter.kt

class LoginPresenter @Inject constructor(private val signInInteractor: SignInInteractor) : LoginContract.Presenter, CoroutineScope {

    private val job = Job()
    override val coroutineContext: CoroutineContext = job + Dispatchers.Main

override fun signInWithCoroutines(email: String, password: String) {

        launch {
            view?.showProgress()
            withContext(Dispatchers.IO){
                signInInteractor.signInWithCoroutinesTest(email,password)
            }
            view?.hideProgress()
        }

    }
}

现在问题出在我的交互器上,因为它是一个挂起功能,我很想返回一个错误响应,以便view.showError(errorMsg)从我的演示者那里做一个

SignInInteractor.kt

 override suspend fun signInWithCoroutinesTest(email: String, password: String) {
        FirebaseAuth.getInstance()?.signInWithEmailAndPassword(email, password).addOnCompleteListener { 
            if(it.isSuccessful){
                //Want to notify the presenter that the coroutine has ended succefully
            }else{
                //want to let the courutine know about it.exception.message.tostring
            }
        }

    }

我这样做的方式是使用通知我的演示者的回调

 override fun signInWithCoroutinesTest(email: String, password: String) {
        FirebaseAuth.getInstance()?.signInWithEmailAndPassword(email, password,listener:OnSuccessCallback).addOnCompleteListener { 
            if(it.isSuccessful){
                listener.onSuccess()
            }else{
                listener.onFailure(it.exception.message.toString())
            }
        }


    }

问题

如果协程操作成功,如何返回并通知我的演示者?

谢谢

标签: androidkotlincoroutinekotlin-coroutinesandroid-mvp

解决方案


您必须显式挂起协程:

override suspend fun signInWithCoroutinesTest(
         email: String, password: String
) = suspendCancellableCoroutine { continuation ->
        FirebaseAuth.getInstance()?.signInWithEmailAndPassword(email, password).addOnCompleteListener { 
            if (it.isSuccessful) {
                continuation.resume(Unit)
            } else {
                continuation.resumeWithException(it.exception)
            }
        }
    }

此外,由于您的代码是可暂停的且不会阻塞,因此请不要运行它withContext(IO)。只需直接从主线程调用它,这就是协程的美妙之处。


推荐阅读