美文网首页Android进阶之路Android开发Android开发经验谈
Kotlin DSL 奇妙用法:结合协程 Coroutine 封

Kotlin DSL 奇妙用法:结合协程 Coroutine 封

作者: ImWiki | 来源:发表于2019-09-30 02:42 被阅读0次

Kotlin 的 DSL是一个神奇的存在,可以帮助我们实现一些非常特别的用法,这里介绍一个类似RxJava的封装。

class ResponseHandler<T> {
    private var onNext: (T) -> Unit = {}
    private var onError: (Throwable) -> Unit = {}
    private var onCompleted: () -> Unit = {}
    private var load: () -> T? = { null }

    fun onNext(onNext: (T) -> Unit) {
        this.onNext = onNext
    }
    fun onError(onError: (Throwable) -> Unit) {
        this.onError = onError
    }
    fun onCompleted(onCompleted: () -> Unit) {
        this.onCompleted = onCompleted
    }
    fun load(load: () -> T?) {
        this.load = load
    }
    fun doWork() {
        try {
            val result = load.invoke()
            if (result != null) {
                onNext.invoke(result)
            }
            onCompleted.invoke()
        } catch (throwable: Throwable) {
            onError.invoke(throwable)
        }
    }
    companion object {
        fun <T> loadData(block: ResponseHandler<T>.() -> Unit) {
            val responseHandler = ResponseHandler<T>()
            block(responseHandler)
            responseHandler.doWork()
        }
    }
}

测试

class ExampleUnitTest {
    @Test
    fun testResponseHandler() {
        println("测试一")
        ResponseHandler.loadData<String> {
            load {
                "Hello World!"
            }
            onNext { println("onNext $it") }
            onCompleted { println("onCompleted") }
            onError { it.printStackTrace() }
        }
        println()
        println("测试二")
        ResponseHandler.loadData<String> {
            load {
                 throw Exception("模拟异常")
            }
            onNext { println("onNext $it") }
            onCompleted { println("onCompleted") }
            onError { it.printStackTrace() }
        }
    }
}

结果

测试一
onNext Hello World!
onCompleted

测试二
java.lang.Exception: 模拟异常

结合协程 Coroutine 封装

class ResponseHandlerCoroutine<T> {
    private var onNext: (T) -> Unit = {}
    private var onError: (Throwable) -> Unit = {}
    private var onCompleted: () -> Unit = {}
    private var load: suspend () -> T? = { null }

    fun onNext(onNext: (T) -> Unit) {
        this.onNext = onNext
    }
    fun onError(onError: (Throwable) -> Unit) {
        this.onError = onError
    }
    fun onCompleted(onCompleted: () -> Unit) {
        this.onCompleted = onCompleted
    }
    fun load(load: suspend () -> T?) {
        this.load = load
    }
    fun doWork() {
        // MainScope().launch {} 如果是Android使用 MainScope()代替GlobalScope
        GlobalScope.launch {
            try {
                val result = withContext(Dispatchers.IO) {
                    load.invoke()
                }
                if (result != null) {
                    onNext.invoke(result)
                }
                onCompleted.invoke()
            } catch (throwable: Throwable) {
                onError.invoke(throwable)
            }
        }
    }
    companion object {
        fun <T> loadData(block: ResponseHandlerCoroutine<T>.() -> Unit) {
            val responseHandler = ResponseHandlerCoroutine<T>()
            block(responseHandler)
            responseHandler.doWork()
        }
    }
}

测试

class ExampleUnitTest {
    @Test
    fun testResponseHandlerCoroutine() {
        println("测试一")
        ResponseHandlerCoroutine.loadData<String> {
            load {
                delay(1000)
                "Hello World!"
            }
            onNext { println("onNext $it") }
            onCompleted { println("onCompleted") }
            onError { it.printStackTrace() }
        }
        Thread.sleep(2000)
        println()
        println("测试二")
        ResponseHandlerCoroutine.loadData<String> {
            load {
                delay(1000)
                throw Exception("模拟异常")
            }
            onNext { println("onNext $it") }
            onCompleted { println("onCompleted") }
            onError { it.printStackTrace() }
        }
        Thread.sleep(2000)
    }
}

输出结果

测试一
onNext Hello World!
onCompleted

测试二
java.lang.Exception: 模拟异常

相关文章

网友评论

    本文标题:Kotlin DSL 奇妙用法:结合协程 Coroutine 封

    本文链接:https://www.haomeiwen.com/subject/rlfcpctx.html