如何在我的api调用中使用协程? MVP模式

时间:2019-06-11 16:40:23

标签: kotlin retrofit kotlin-coroutines

我在coroutines上还很陌生,我想知道自己做错了什么... 我有一个正在返回Object

的服务
 @GET("list/{id}")
    suspend fun getId(@Path("id") id: Long): Response<MyListResponse>

所以,现在我有一个演示者调用用例,而我的用例正在这样做:

class MyUseCase(val repoImpl: MyRepoImpl) {
    suspend fun execute(id: Long) = repoImpl.getListById(id)
}

然后我的存储库是:

class MyRepository(val myService : MyService) {
 suspend fun getResult(id: Long) = myService.getId(id)

我不知道我在想什么,我应该在哪里做协同程序?

我正在使用此BaseRepository

open class BaseRepository {

    suspend fun <T : Any> safeApiCall(call: suspend () -> Response<T>, errorMessage: String): T? {

        val result: Result<T> = safeApiResult(call, errorMessage)
        var data: T? = null

        when (result) {
            is Result.Success ->
                data = result.data
            is Result.Error -> {
                Log.d("1.DataRepository", "$errorMessage & Exception - ${result.exception}")
            }
        }

        return data

    }

    private suspend fun <T : Any> safeApiResult(call: suspend () -> Response<T>, errorMessage: String): Result<T> {
        val response = call.invoke()
        if (response.isSuccessful) return Result.Success(response.body()!!)

        return Result.Error(IOException("Error Occurred during getting safe Api result, Custom ERROR - $errorMessage"))
    }

}

ResultsealedSuccess的{​​{1}}类,但是很多人告诉我Error是CRUD的东西,所以应该去我的用例。

我缺少什么?

1 个答案:

答案 0 :(得分:0)

如果您使用的是ViewModel或Presenter,建议您在此处启动协程。 ViewModel已经具有其viewModelScope(从2.1.0版开始),演示者可以实现CoroutineScope。这将使它在不再需要时很容易取消。VM会发生什么:

fun foo(){
viewModelScope.launch(Dispatchers.Main){
  val result = myUseCase.execute(id = 1)
  // stuff happens
   }
}

请注意,我已经使用Dispatchers.Main进行了api调用-改进的暂停功能支持使您可以做到这一点。

**编辑**

由于作者正在使用MVP

您可以做什么:

class AwesomePresenter :  CoroutineScope by CoroutineScope(Dispatchers.Main){

fun foo()
launch{
  val result = myUseCase.execute(id = 1)
  // stuff happens
   }
}

fun destroy()/* or whatever your detach/destroy method is called */{
    cancel()
}

}