我想使用協程一次呼叫多個 API 呼叫。到目前為止,我只使用協程來呼叫單個 API 呼叫,該呼叫以成功或錯誤的形式回傳結果。它使用行內函式。但我需要了解如何將這個行內函式引數用于資料類。
類JsonResponse是開放類,它是每個 API 呼叫的結果。但是如果我T在我的資料類中使用它,它是紅色的。如果我在那里使用 type JsonResponse,它是回傳JsonResponse型別,但不是應該apiBlock回傳的確切型別。
示例:apiBlock可以包含任務,它將回傳LoginResponse. LoginResponse 正在擴展JsonResponse。但是如果我在我的資料類中使用JsonResponse,T我將JsonResponse在我的onSuccess回呼中使用泛型。
我的目標是初始化多個任務,在協程中異步運行它們,然后等待所有任務完成,如果其中一些任務失敗,則將失敗的任務作為陣列回傳,以便再次呼叫它們。
這是我想要實作的代碼:
data class ApiTask(
val apiBlock: suspend CoroutineScope.() -> T,
val onSuccess: suspend (T)->Unit)
protected fun<T: JsonResponse> apiCallChained(
apiBlocks: List<ApiTask>,
one rror: ((List<ApiTask>)->Unit),
onSuccess: ()->Unit){
val failedTasks = mutableListOf<ApiTask>()
apiBlocks.forEach { apiBlock->
launch(Dispatchers.Main){
val (r, err) = withContext(Dispatchers.IO){
try {
apiBlock.apiBlock(this) to null
} catch (e: ApiCallError) {
null to e
}
}
when {
r != null -> {
apiBlock.onSuccess(r)
}
err != null -> failedTasks.add(apiBlock)
}
}
}
if (failedTasks.isEmpty()) onSuccess.invoke() else one rror.invoke(failedTasks)
}
這是我的單個 API 呼叫的作業示例:
protected fun<T: JsonResponse> apiCall(apiBlock: suspend CoroutineScope.() -> T,
one rror: ((ApiCallError)->Unit)? = null,
onDone: (()->Unit)? = null,
onSuccess: suspend (T)->Unit): Job {
return launch(Dispatchers.Main){
val (r, err) = withContext(Dispatchers.IO){
try {
apiBlock() to null
} catch (e: ApiCallError) {
null to e
}
}
onDone?.invoke()
when {
r != null -> onSuccess(r)
err != null -> {
one rror?.invoke(err)
}
}
}
}
ApiBlock 引數值示例:
class ApiLogin(js: JSONObject): JsonResponse(js) {
companion object {
@Throws(ApiCallError::class)
operator fun invoke(api: AppApi, email: String, pass: String): ApiLogin{
return ApiLogin(api.apiLoginUser(email, pass))
}
}
class LoginServerResponse(js: JSONObject): JsonResponse(js){
val httpCode by JsInt("httpCode")
val session by JsString("session")
}
val r = LoginServerResponse(js)
}
然后將此類用作
apiBlock = { ApiLogin(app.api, email, pass) }
更新:像這樣修復它,它的作業。
data class ApiTask<out T: JsonResponse>(
val apiBlock: suspend CoroutineScope.() -> T,
val onSuccess: suspend (@UnsafeVariance T)->Unit)
uj5u.com熱心網友回復:
您ApiTask還需要一個通用引數:
data class ApiTask<T : JsonResponse>(
val apiBlock: suspend CoroutineScope.() -> T,
val onSuccess: suspend (T) -> Unit
)
然后你必須在apiCallChained函式中添加這個通用引數:
protected fun <T : JsonResponse> apiCallChained(
apiBlocks: List<ApiTask<T>>,
one rror: ((List<ApiTask<T>>) -> Unit),
onSuccess: () -> Unit
) {
val failedTasks = mutableListOf<ApiTask<T>>()
apiBlocks.forEach { apiBlock ->
launch(Dispatchers.Main) {
val (r, err) = withContext(Dispatchers.IO) {
try {
apiBlock.apiBlock(this) to null
} catch (e: ApiCallError) {
null to e
}
}
when {
r != null -> {
apiBlock.onSuccess(r)
}
err != null -> failedTasks.add(apiBlock)
}
}
}
if (failedTasks.isEmpty()) onSuccess.invoke() else one rror.invoke(failedTasks)
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/520074.html
上一篇:滿足特定條件時如何僅回傳串列流?
下一篇:kotlin中的布爾條件未執行
