Kotlin DSL 實戰

目標數據庫

首先,定義好異步結果泛化類型AsyncResult,此處會用到Kotlin泛型編程基礎知識:編程

sealed class AsyncResult<out T : Any>

data class AsyncSuccess<out T : Any>(val data: T?) : AsyncResult<T>()

data class AsyncError(val error: String?) : AsyncResult<Nothing>()

inline fun <T : Any> AsyncResult<T>.onSuccess(action: (T?) -> Unit): AsyncResult<T> {
    if (this is AsyncSuccess) action(data)
    return this
}

inline fun <T : Any> AsyncResult<T>.onError(action: (String) -> Unit) {
    if (this is AsyncError && error != null) action(error)
}
複製代碼

基於此AsyncResult和Kotlin協程suspend關鍵字,能夠定義任意異步操做(網絡請求,數據庫操做等)以下:bash

suspend fun demoAction(): AsyncResult<List<DemoItem>> {
    //請暫時忽略實現方法
  }
複製代碼

接下來好戲登場,UI部分的代碼:網絡

launch {
            demoAction()
                .onSuccess {
                    Toast.makeText(this@MainActivity, "Successfully Fetched ${it?.size} Items", Toast.LENGTH_LONG)
                        .show()
                }

                .onError {
                    Toast.makeText(this@MainActivity, "Failed!! -- $it", Toast.LENGTH_LONG).show()
                }
        } 
複製代碼

很是優雅有木有?!異步

具體操做(實現)函數

展現過了魔術效果, 咱們來揭祕下幾處關鍵手法:ui

  • sealed class 描述了受限的類繼承結構,即限定了此類實例只能是有限的幾種類型。 AsyncSuccess和AsyncError則是AsyncResult的派生類而已。
  • onSuccess和oError是AsyncResult的擴展方法(Kotlin能夠給已知的任何 class 類添加函數), 其中onSuccess還返回了自身對象,以便鏈式調用。
  • onSuccess和onError均接受惟一一個Lambda參數, 從而能夠實現形式上onSuccess{}.onError{}的寫法。
相關文章
相關標籤/搜索