rn-collie
Version:
A UI library for react native.
97 lines (89 loc) • 2.96 kB
JavaScript
import BaseInterceptor from "./BaseInterceptor";
export default class Proxy<T> {
_instance: T = null;
_currentFun: string = null;
_isObject: boolean = true;
constructor(instance: T) {
this._instance = instance;
Object.keys(instance).forEach((key) => {
if (typeof instance[key] === 'function') {
this[key] = function () {
instance[key](...arguments);
}
} else {
this[key] = instance[key];
}
})
}
/**
* 创建一个代理
* @param object
* @returns {Proxy}
*/
static create(object: Object | Function) {
let type = typeof object;
if (type === 'object') {
return new Proxy(object);
} else {
let proxy = new Proxy({
next: object,
});
proxy._isObject = false;
return proxy;
}
}
/**
* 执行最近被拦截的方法
*/
next() {
if (this._currentFun) {
this[this._currentFun](...arguments);
}
}
/**
* 拦截具体的方法,可传多个拦截器,进行链式拦截
* @param fun 需要拦截的方法名字或者拦截器,如果拦截的是对象,则此参数为被拦截的方法的名字,否则此参数为拦截器
* @param interceptors 多个拦截器
*/
intercept(fun?: string | BaseInterceptor, ...interceptors: Array<BaseInterceptor>) {
let invokeFunStr;
if (this._isObject) {
if ((typeof fun) !== 'string') {
throw new Error('proxy Object ,intercept first args need string')
}
invokeFunStr = fun;
} else {
interceptors = [fun, ...interceptors];
invokeFunStr = 'next';
}
let thiz = this;
this[invokeFunStr] = function () {
let args = arguments;
let realFun = thiz._instance[invokeFunStr];
if (interceptors.length === 0) {
realFun(...args);
} else {
thiz.exeInterceptor(0, interceptors, realFun, args);
}
};
thiz._currentFun = invokeFunStr;
return this;
}
exeInterceptor(index: number, interceptors: Array<BaseInterceptor>, fun: Function, args: Array<any>) {
if (index < interceptors.length) {
interceptors[index].handle(args).then((consume) => {
if (index >= interceptors.length - 1) {
if (!consume) {
fun(...args);
}
} else {
if (!consume) {
this.exeInterceptor(index + 1, interceptors, fun, args);
}
}
}).catch((e: Error) => {
console.log("interceptor execute throw:" + e.message);
});
}
}
}