如何使用协程Flow定义链式调用DSL

9 篇文章 0 订阅
8 篇文章 0 订阅

定义DSL

定义启动flow的函数:


    protected val _spinner: MutableLiveData<Boolean> by lazy { MutableLiveData<Boolean>() }
    val spinner: LiveData<Boolean>
        get() = _spinner
        
    fun <T> loadAsync(showSpinner: Boolean = true, block: suspend () -> T): Flow<T> {
        if (showSpinner) {
            _spinner.value = true
        }
        return block.asFlow()
    }

定义变换函数:

    fun <T, R> Flow<T>.then(block: suspend (T) -> R): Flow<R> {
        return this.flatMapConcat { flow { block(it) } }
    }

定义订阅函数:


 protected val uiScope = CoroutineScope(Dispatchers.main
                    + viewModelJob
                    + CoroutineExceptionHandler { _, exception ->
                		Logger.e("caught original $exception")})
                		
 fun <T> Flow<T>.result(success: (T) -> Unit,
                        error: (Throwable) -> Unit = { _errorToast.value = it.message }) {
        uiScope.launch {
            this@result.flowOn(Dispatchers.io)
                    .catch { cause ->
                        val err = cause as? AccessThrowable
                        when (err?.code) {
                            ERROR.ERROR_NETWORK -> {
                                _networkError.postValue(err)
                            }
                            ERROR.ERROR_TOKEN_EXPIRED -> {
                                _reLogin.postValue(true)
                            }
                        }
                        if (err == null) {
                            error(AccessThrowable(ERROR.UNKNOWN, cause.message ?: ""))
                        } else {
                            error(err)
                        }
                    }.onCompletion {
                        if (_spinner.value == true) {
                            _spinner.value = false
                        }
                    }.collect {
                        success.invoke(it)
                    }
        }
    }

如何使用?

fun function(...parameters...) {
        loadAsync {
        	//suspend function,which returns bool
            repo.function1(...parameters...)
        }.then {
            if (it) {
                //suspend function
                repo.function2(...parameters..)
            } else throw AccessThrowable(ERROR.UNKNOWN, "失败")
        }.result({
            _value.postSuccess(it)
        }, {
            _value.postError(it)
        })
    }

由于Flow属于实验性质的,暂时用Rx代替,这需要使用coroutines的Rx扩展包

定义启动flow的函数:

                		
    protected val _spinner: MutableLiveData<Boolean> by lazy { MutableLiveData<Boolean>() }
    val spinner: LiveData<Boolean>
        get() = _spinner
        
    fun <T : Any> loadAsync(showSpinner: Boolean = true,
                            block: suspend CoroutineScope.() -> T): Single<T> {
        if (showSpinner) {
            _spinner.value = true
        }
        return rxSingle(block = block)
    }

定义变换函数:

    fun <T : Any, R : Any> Single<T>.then(block: suspend CoroutineScope.(T) -> R): Single<R> {
        return flatMap {
            rxSingle { block(it) }
        }
    }

定义订阅函数:

    fun <T> Single<T>.result(success: (T) -> Unit,
                           error: (AccessThrowable) -> Unit = { _errorToast.value = it.message }) {
        disposable = subscribeOn(schedulers.io)
                .observeOn(schedulers.main)
                .subscribe({
                    if (_spinner.value == true) {
                        _spinner.value = false
                    }
                    success.invoke(it)
                },{
                    if (_spinner.value == true) {
                        _spinner.value = false
                    }
                    (it as? AccessThrowable)?.run { error.invoke(this) }
                })
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值