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