簡體   English   中英

發送 Kotlin 掛起方法作為參數

[英]send Kotlin suspend method as parameter

這是我在retrofit界面中的function

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

我需要將此 patientLogin(data) 方法作為參數發送到另一個方法中,該方法應該是一個通用方法,它將在 IO scope 中調用此方法,並將返回帶有偵聽器(接口)的響應。 唯一的問題是我不確定如何將此方法本身作為參數發送。 謝謝

// 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()
}

所以最后我能夠做我想做的事,我只是想我也應該發布答案,這可能對其他人有幫助。 感謝所有回答我問題的貢獻者。

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)

我只是遇到了同樣的問題,您在參數定義中的“暫停”對我有所幫助。

有人可以通過這個例子找到一些清晰度:

import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

class Worker {

    fun doWork() {
        println("Start work")
        Thread.sleep(1000)
        println("End work")
    }

    suspend fun doWorkSuspend() = withContext(Dispatchers.Default) {
        println("Start work suspended")
        Thread.sleep(1000)
        println("End work suspended")
    }

}

import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch

class Controller {
    private val scope = CoroutineScope(Dispatchers.Default)
    private val startedJobs = mutableListOf<Job>()

    fun launchWork(perform: () -> Unit) {
        perform()
    }

    fun launchWorkSuspended(perform: suspend() -> Unit) {
        val job = scope.launch {
            perform()
        }
        startedJobs.add(job)
    }

}

fun main(args: Array<String>) {

    val controller = Controller()
    val worker = Worker()

    controller.launchWork { worker.doWork() } // fine
    controller.launchWorkSuspended { worker.doWork() } // fine
    controller.launchWorkSuspended { worker.doWorkSuspend() } // fine

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM