【问题标题】:send Kotlin suspend method as parameter发送 Kotlin 挂起方法作为参数
【发布时间】:2021-10-10 03:50:18
【问题描述】:

这是我在改造界面中的功能

@POST("/api/Auth/login")
suspend fun patientLogin(@Body loginReq: LoginRequest): Response<BaseResponse<User>>

我需要将这个 patientLogin(data) 方法作为参数发送到另一个方法中,该方法应该是一个通用方法,它将在 IO 范围内调用此方法并返回带有侦听器(接口)的响应。唯一的问题是我不确定如何将此方法本身作为参数发送。谢谢你

【问题讨论】:

    标签: android kotlin retrofit kotlin-coroutines


    【解决方案1】:
    // One cannot return caculcated value from a coroutine, only the job
    fun <T, R> CoroutineScope.functionName(block: suspend (T) -> R): Job = launch(Dispatchers.IO) {
        block() //provide T either as another parameter to this function or if this function belongs to a class you take it from a class' state
    }
    
    // One can return a deferred value and wait for the actual R value to be calculated
    fun <T, R> CoroutineScope.functionName(block: suspend (T) -> R): Deferred<R> = async(Dispatchers.IO) {
        block()
    }
    
    // Will execute on the inherited dispatcher from the coroutine that executes this function
    suspend fun <T, R> functionName(block: suspend (T) -> R): R = coroutineScope {
        block()
    }
    
    // Always executes on the IO dispatcher
    suspend fun <T, R> functionName(block: suspend (T) -> R): R = withContext(Dispatchers.IO) {
        block()
    }
    

    【讨论】:

      【解决方案2】:

      所以最后我能够做我想做的事,尽管我也应该发布答案,这可能对其他人有帮助。感谢所有回答我问题的贡献者。

      fun <T : Any> callBaseApi(call: suspend () -> Response<BaseResponse<T>>, apiCallback: ApiCallback<T>) {
          CoroutineScope(Dispatchers.IO).launch {
             try {
                 val response = call.invoke()
      
                 withContext(Dispatchers.Main) {
                     if (response.isSuccessful) {
                         apiCallback.onSuccess(
                             response.body()?.data,
                             response.body()?.message,
                             response.body()?.status!!
                         )
                     } else {
                         apiCallback.onFailure(response.message(), response.code())
                         Log.e("makeApiCall: ", response.errorBody().toString())
                     }
                 }
             }catch (e:Exception){
                 withContext(Dispatchers.Main) {
                     apiCallback.onFailure(e.message, -1)
                 }
             }
          }
      }
      

      并调用此方法

      callBaseApi({WebServicesHandler.getWebServices(CacheManager.getCurrentUser()!!.token!!)
                  .editPatientPersonalInfo(data)}, apiCallback)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-06-25
        • 1970-01-01
        • 2021-02-20
        • 2020-01-27
        • 2017-09-01
        • 1970-01-01
        • 2019-07-02
        • 1970-01-01
        相关资源
        最近更新 更多