将 Kotlin 挂起方法作为参数发送
send Kotlin suspend method as parameter
这是我改造界面的功能
@POST("/api/Auth/login")
suspend fun patientLogin(@Body loginReq: LoginRequest): Response<BaseResponse<User>>
我需要将此 patientLogin(data) 方法作为参数发送到另一个方法中,该方法应该是一个通用方法,它将在 IO 范围内调用此方法,并将 return 与侦听器(接口)的响应).唯一的问题是我不确定如何将此方法本身作为参数发送。谢谢
// 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()
}
所以我终于能够做我想做的事了,我只是觉得我也应该 post 答案,这可能对其他人有帮助。感谢所有回答我问题的贡献者。
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)
我刚刚遇到了同样的问题,您在参数定义中的 'suspend' 帮助了我。
有人可以通过这个例子找到一些清晰的信息:
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
}
这是我改造界面的功能
@POST("/api/Auth/login")
suspend fun patientLogin(@Body loginReq: LoginRequest): Response<BaseResponse<User>>
我需要将此 patientLogin(data) 方法作为参数发送到另一个方法中,该方法应该是一个通用方法,它将在 IO 范围内调用此方法,并将 return 与侦听器(接口)的响应).唯一的问题是我不确定如何将此方法本身作为参数发送。谢谢
// 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()
}
所以我终于能够做我想做的事了,我只是觉得我也应该 post 答案,这可能对其他人有帮助。感谢所有回答我问题的贡献者。
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)
我刚刚遇到了同样的问题,您在参数定义中的 'suspend' 帮助了我。
有人可以通过这个例子找到一些清晰的信息:
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
}