Android Kotlin 仿写 JS Promise 链式

2022-03-09  本文已影响0人  o简单生活o

感觉在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,喜欢的朋友记得点个赞

上一篇下一篇

猜你喜欢

热点阅读