美文网首页
Android Kotlin 仿写 JS Promise 链式

Android Kotlin 仿写 JS Promise 链式

作者: o简单生活o | 来源:发表于2022-03-09 20:25 被阅读0次

    感觉在Kotlin上写Retrofit2的网络请求好麻烦
    想到之前在JS上用的链式请求就想模仿一下
    搞了2天差不多
    这Kotlin语法刚接触,各种不习惯
    各种百度,加上自己的一些理解,做出了最基本的then和catch的链式调用
    没有做过多的测试,各位大佬帮忙测试下
    貌似不卡UI


    贴出代码:

    package com.mqry.utility
    
    import kotlinx.coroutines.*
    import java.lang.Exception
    import java.lang.Runnable
    
    class Promise() {
    
        //region 状态枚举
        enum class PROMISE_STATUS {
            PENDING, RESOLVE, REJECT
        }
        //endregion
    
        //region 属性
        private var _status = PROMISE_STATUS.PENDING
        private var _value: Any? = null
    
        //未执行的Promise
        private var _nextPromise: Promise? = null
        private var _thisTimeOnResolve: ((Any?) -> Promise)? = null
        private var _thisTimeOnReject: ((Any?) -> Unit)? = null
        //endregion
    
        //region 构造函数
        constructor(executer: (resolve: (result: Any?) -> Unit, reject: (result: Any?) -> Unit) -> Unit) : this() {
            var that = this
            GlobalScope.launch() {
                try {
                    executer(that::_resolve, that::_reject)
                } catch (e: Exception) {
                    _reject(e.message.toString())
                }
            }
        }
    
        constructor(status: PROMISE_STATUS, value: Any? = null) : this() {
            var that = this
            that._status = status
            that._value = value
        }
        //endregion
    
        //region 处理函数
        /**
         * 成功处理
         */
        private fun _resolve(result: Any? = null) {
    
            this._value = result
            this._status = PROMISE_STATUS.RESOLVE
    
            //之前的then没有执行完成,手动执行一次
            if (this._nextPromise != null && this._thisTimeOnResolve != null) {
    
                var promise = try {
                    //结果他没执行完
                    _thisTimeOnResolve!!(this._value)
                } catch (e: Exception) {
                    Promise.Reject(e.message.toString())
                }
    
                var maxCount = 0
                //最好的办法,还是等待他处理完
                while (promise._status == PROMISE_STATUS.PENDING) {
                    Thread.sleep(100)
                    maxCount++
                    if (maxCount > 1000) {//超过100秒算失败
                        promise._status = PROMISE_STATUS.REJECT
                    }
                }
    
                if (promise._status == PROMISE_STATUS.RESOLVE) {
                    this._nextPromise!!._resolve(promise._value)
                }
    
                if (promise._status == PROMISE_STATUS.REJECT) {
                    this._nextPromise!!._reject(promise._value)
                }
            }
        }
    
        /**
         * 失败处理
         */
        private fun _reject(result: Any? = null) {
            this._value = result
            this._status = PROMISE_STATUS.REJECT
    
            if (_thisTimeOnReject == null) {
                this._nextPromise?._reject(this._value)
            } else {
                _thisTimeOnReject!!(this._value)
            }
    
        }
        //endregion
    
        //region 核心方法
        fun then(onResolve: (result: Any?) -> Promise): Promise {
    
            //当下就成功了
            if (_status == PROMISE_STATUS.RESOLVE) {
                try {
                    return onResolve(_value)
                } catch (e: Exception) {
                    return Promise.Reject(e.message.toString())
                }
            }
    
            //当下就失败了
            if (_status == PROMISE_STATUS.REJECT) {
                return this
            }
    
            //未执行完成
            if (_status == PROMISE_STATUS.PENDING) {
                _thisTimeOnResolve = onResolve
                _nextPromise = Promise()
                return _nextPromise as Promise
            }
    
            throw Exception("未知错误!")
        }
    
        fun catch(onReject: (result: Any?) -> Unit) {
            if (_status == PROMISE_STATUS.REJECT) {
                onReject(_value)
            }
    
            //未执行完成
            if (_status == PROMISE_STATUS.PENDING) {
                _thisTimeOnReject = onReject
    //            _nextPromise = Promise()
            }
        }
        //endregion
    
        //region 静态方法
        /**
         * 静态方法
         */
        companion object {
    
            /**
             * 成功处理
             */
            fun Resolve(value: Any? = null): Promise {
                return Promise(PROMISE_STATUS.RESOLVE, value)
            }
    
            /**
             * 失败处理
             */
            fun Reject(value: Any? = null): Promise {
                return Promise(PROMISE_STATUS.REJECT, value)
            }
    
        }
        //endregion
    }
    

    调用示例:

    Promise { resolve, reject ->
                run {
                    //IO操作,类似网络请求
                    if (true) {//网络请求成功后,得到返回值
                        resolve("JSON数据")
                    } else {
                        reject("ERROR数据")
                    }
                }
            }
                .then { r ->
                    //r 就是上一步的JSON数据
                    Log.i("XX", r as String)
                    Thread.sleep(1000)
                    //继续其他的IO操作
                    //得到一个结果,继续往下传递
                    Promise.Resolve("第二步结果")
                }.then { r ->
                    //r 就是上一步的数据
                    Log.i("XX", r as String)
                    Thread.sleep(1000)
                    //继续其他的IO操作
                    //得到一个结果,继续往下传递
                    Promise.Resolve("第三步结果")
                }
                .then { r ->
                    //r 就是上一步的数据
                    Log.i("XX", r as String)
                    Thread.sleep(1000)
                    //继续其他的IO操作
                    //得到一个结果,继续往下传递
                    //模拟这一步失败
                    Promise.Reject("失败数据")
                }.then { r ->
                    //r 就是上一步的数据
                    Log.i("XX", r as String)
                    Thread.sleep(1000)
                    //继续其他的IO操作
                    //得到一个结果,继续往下传递
                    //由于上一步失败了,这个函数不会执行
                    Promise.Resolve("由于上一步失败了,这个函数不会执行")
                }
                .catch { r ->
                    //失败的数据
                    //做一些失败处理
                    Log.i("XX", "错误数据:" + r as String)
                }
    
    

    日志记录:

    p1.png

    作为兴趣爱好写的,目前感觉没什么BUG,喜欢的朋友记得点个赞

    相关文章

      网友评论

          本文标题:Android Kotlin 仿写 JS Promise 链式

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