TypeScript之多方法执行方案
作者:互联网
一, 情景
①,A,B,C,D四个方法都执行完毕之后再执行E方法
②,A,B,C,D四个方法有其中任意一个执行完毕后再执行E方法
注意: A、B,C,D 可以是普通方法, 也可以是异步方法 ,可以带参数, 也可以没有参数
二,解决方案
①,BaseMultiFunctionExecute.ts (对方法执行基类)
/**
* 多方法执行基类
* @author Husz
*/
abstract class BaseMultiFunctionExecute<T extends IMultiFunctionData>{
protected _list: Array<T>;
protected _callback: (tag: string, sender: any, ...arg) => void;
protected _mgrCb: (tag: string, sender: any, ...arg) => void;
protected _isExeing: boolean = false;//是否正在处理中
protected _curIndex: number;
protected _inPool: boolean = false;
protected _tag: string;
/**
* 是否在对象池
*/
public set InPool(value: boolean) {
this._inPool = value;
}
/**
* 是否在对象池
*/
public get InPool(): boolean {
return this._inPool;
}
public constructor(tag: string, list: Array<{ exeFun: Function, sender: any, isPromise?: boolean, exeParams?: Array<any> }>, callback: (tag: string, sender: any, ...arg) => void, mgrCb: (tag: string, sender: any, ...arg) => void) {
this._mgrCb = mgrCb;
this.resetData(tag, list, callback);
}
/**
* 获取类型
*/
public abstract getType(): Ty2MultiFunctions;
/**
* 重置数据
*/
public resetData(tag: string, list: Array<{ exeFun: Function, sender: any, isPromise?: boolean, exeParams?: Array<any> }>, callback: (tag: string, sender: any, ...arg) => void): void {
if (this._inPool) return;
this._tag = tag;
this._list = this.getList(list);
this._callback = callback;
}
/**
* 获取list数据
*/
protected getList(list: Array<{ exeFun: Function, sender: any, isPromise?: boolean, exeParams?: Array<any> }>): Array<T> {
if (list == null || list.length == 0) return [];
let cell: { exeFun: Function, sender: any, isPromise?: boolean, exeParams?: Array<any> };
let bc: Array<T> = [];
for (let i: number = 0, j: number = list.length; i < j; i++) {
cell = list[i];
bc.push(<T><any>{
exeFun: cell.exeFun,
sender: cell.sender,
isPromise: cell.isPromise != null ? cell.isPromise : false,
isSucc: false,
exeParams: cell.exeParams == null || cell.exeParams.length < 0 ? null : cell.exeParams,
complete: false
});
}
return bc;
}
/**
* @return 是否添加成功
*/
public addItem(cell: { exeFun: Function, sender: any, isPromise?: boolean, exeParams?: Array<any> }): boolean {
if (this._isExeing || !cell || this._inPool) return false;
let data: T = <T><any>{
exeFun: cell.exeFun,
sender: cell.sender,
isPromise: cell.isPromise != null ? cell.isPromise : false,
isSucc: false,
exeParams: cell.exeParams == null || cell.exeParams.length < 0 ? null : cell.exeParams,
complete: false
};
if (this._list) {
this._list.push(data);
} else {
this._list = [data];
}
return true;
}
/**
* 开始处理数据(入口)
*/
public async startExe(): Promise<void> {
return new Promise<void>(resolve => {
if( this._isExeing || this._inPool){
resolve();
return;
}
if (this._list == null || this._list.length == 0 ) {
this._callback(`exe_complete`, this, this._tag);
this._mgrCb(`over`, this, this._tag);
resolve();
} else {
this.exeFunctions();
resolve();
}
});
}
/**
* 执行方法
*/
protected exeFunctions(): void {
this._isExeing = true;
this._curIndex = 0;
}
/**
* 检测是否已经做完
* @param data
*/
protected checkOver(data: T, isSucc: boolean): void {
data.complete = true;
data.isSucc = isSucc;
this.addCopletaTag();
}
/**
* 处理完成计数
*/
protected addCopletaTag(): void {
this._curIndex++;
if (this._curIndex >= this._list.length) {
this._callback(`exe_complete`, this, this._tag);
this._mgrCb(`over`, this);
}
}
/**
* 清理
*/
public clear(): void {
this._isExeing = false;
this._list = null;
this._inPool = true;
}
/**
* @return { complete: 是否执行完毕, isSucc: 是否执行成功 }
*/
public isFunComplete(exeFun: Function): { complete: boolean, isSucc: boolean } {
if (!this._list || this._list.length == 0 || this._inPool) return { complete: false, isSucc: false };
let data: T;
for (let i: number = 0, j: number = this._list.length; i < j; i++) {
data = this._list[i];
if (data.exeFun == exeFun) {
if (data.complete == null && data.complete == false) {
return { complete: false, isSucc: false };
} else {
return { complete: true, isSucc: data.isSucc }
}
}
}
return { complete: false, isSucc: false };
}
/**
* 销毁
*/
public destroy(): void {
this._callback = null;
this._list = null;
this._mgrCb = null;
}
}
/**
* 多方法执行单元数据
* @author Husz
*/
interface IMultiFunctionData {
exeFun: Function;
sender: any;
complete?: boolean;
exeParams?: Array<any>;
isPromise: boolean;//是否是异步方法
isSucc?: boolean;//是否执行成功
}
②,TogetherExecute.ts (全部执行完毕后执行E 子类)
/**
* 全部执行
* @author Husz
*/
class TogetherExecute extends BaseMultiFunctionExecute<IMultiFunctionData>{
/**
* @inheritDoc
*/
protected exeFunctions(): void {
super.exeFunctions();
this.stepDoFunctions(this._curIndex);
}
/**
* @inheritDoc
*/
public getType(): Ty2MultiFunctions {
return Ty2MultiFunctions.___TOGETHER___;
}
/**
* 处理异步方法
*/
private doPomise(data: IMultiFunctionData): void {
if (data.sender != null) {
data.exeFun.bind(data.sender);
}
if (data.exeParams != null && data.exeParams.length > 0) {
data.exeFun(...data.exeParams).then(() => {
this.checkOver(data, true);
}).catch(() => {
this.checkOver(data, false);
});
} else {
data.exeFun().then(() => {
this.checkOver(data, true);
}).catch(() => {
this.checkOver(data, false);
});
}
}
/**
* 分步执行方法
*/
private stepDoFunctions: (index: number) => void = (index) => {
if (index < this._list.length) {
let data: IMultiFunctionData = this._list[index];
if (data.isPromise) {
this.doPomise(data);
} else {
if (data.sender) {
if (data.exeParams != null && data.exeParams.length > 0) {
data.exeFun.call(data.sender, ...data.exeParams);
} else {
data.exeFun.call(data.sender);
}
} else {
if (data.exeParams != null && data.exeParams.length > 0) {
data.exeFun(...data.exeParams);
} else {
data.exeFun();
}
}
this.checkOver(data, true);
}
index++;
this.stepDoFunctions(index);
}
};
}
③,OtherExecute.ts (任意方法执行完毕执行E 子类)
/**
* 其中一个完成
* @author Husz
*/
class OtherExecute extends BaseMultiFunctionExecute<IMultiFunctionData>{
/**
* @inheritDoc
*/
protected addCopletaTag(): void {
this._curIndex++;
if (this._curIndex == 1) {
this._callback(`exe_complete`, this, this._tag);
}
if (this._curIndex >= this._list.length) {
this._mgrCb(`over`, this); // 通知管理器处理结束
// this._callback( `all_complete` , this );
}
}
/**
* @inheritDoc
*/
public getType(): Ty2MultiFunctions {
return Ty2MultiFunctions.___OTHER___;
}
/**
* @inheritDoc
*/
protected exeFunctions(): void {
super.exeFunctions();
this.stepDoFunctions(this._curIndex);
}
/**
* 处理异步方法
*/
private doPomise(data: IMultiFunctionData): void {
if (data.sender != null) {
data.exeFun.bind(data.sender);
}
if (data.exeParams != null && data.exeParams.length > 0) {
data.exeFun(...data.exeParams).then(() => {
this.checkOver(data, true);
}).catch(() => {
this.checkOver(data, false);
});
} else {
data.exeFun().then(() => {
this.checkOver(data, true);
}).catch(() => {
this.checkOver(data, false);
});
}
}
/**
* 分步执行方法
*/
private stepDoFunctions: (index: number) => void = (index) => {
if (index < this._list.length) {
let data: IMultiFunctionData = this._list[index];
if (data.isPromise) {
this.doPomise(data);
} else {
if (data.sender) {
if (data.exeParams != null && data.exeParams.length > 0) {
data.exeFun.call(data.sender, ...data.exeParams);
} else {
data.exeFun.call(data.sender);
}
} else {
if (data.exeParams != null && data.exeParams.length > 0) {
data.exeFun(...data.exeParams);
} else {
data.exeFun();
}
}
this.checkOver(data, true);
}
this.stepDoFunctions(++index);
}
};
}
④,MultiFunctionsMgr.ts (多方法执行管理器)
/**
* 多方法执行管理器
* @author Husz
*/
class MultiFunctionsMgr {
private static _instance: MultiFunctionsMgr;
public static get Instance(): MultiFunctionsMgr {
if (!MultiFunctionsMgr._instance)
MultiFunctionsMgr._instance = new MultiFunctionsMgr();
return MultiFunctionsMgr._instance;
}
private _list: Map<Ty2MultiFunctions, PoolObject<BaseMultiFunctionExecute<any>>>;
private constructor() {
this._list = new Map<Ty2MultiFunctions, PoolObject<BaseMultiFunctionExecute<any>>>();
}
private createExe(tag: string, ty: Ty2MultiFunctions, list: Array<{ exeFun: Function, sender: any, isPromise?: boolean, exeParams?: Array<any> }>, callback: (tag: string, sender: any, ...arg) => void): BaseMultiFunctionExecute<any> {
switch (ty) {
case Ty2MultiFunctions.___TOGETHER___:
return new TogetherExecute(tag, list, callback, this.onStandardCallback);
case Ty2MultiFunctions.___OTHER___:
return new OtherExecute(tag, list, callback, this.onStandardCallback);
}
}
/**
* 获取执行句柄
*/
public getExeFun(tag: string, ty: Ty2MultiFunctions, list: Array<{ exeFun: Function, sender: any, isPromise?: boolean, exeParams?: Array<any> }>, callback: (tag: string, sender: any, ...arg) => void): BaseMultiFunctionExecute<any> {
let cell: BaseMultiFunctionExecute<any>;
if (this._list.has(ty)) {
let pool: PoolObject<BaseMultiFunctionExecute<any>>;
pool = this._list[ty];
cell = pool.Cell;
if (!cell) {
cell = this.createExe(tag, ty, list, callback);
} else {
cell.InPool = false;//从对象池中提取出来了
cell.resetData(tag, list, callback);
}
} else {
cell = this.createExe(tag, ty, list, callback);
}
return cell;
}
/**
* 标准回调
*/
private onStandardCallback: (tag: string, sender: any, ...arg) => void = (tag, sender, ...arg) => {
switch (tag) {
case `over`:
(sender as BaseMultiFunctionExecute<any>).clear();
let ty: Ty2MultiFunctions = (sender as BaseMultiFunctionExecute<any>).getType();
let pool: PoolObject<BaseMultiFunctionExecute<any>>;
if (this._list.has(ty)) {
pool = this._list[ty];
if (!pool.push(sender)) {
(sender as BaseMultiFunctionExecute<any>).destroy();
}
} else {
pool = new PoolObject<BaseMultiFunctionExecute<any>>(2);
pool.push(sender);
this._list.set(ty, pool);
}
break;
}
};
}
/**
* 执行类型
* @author Husz
*/
enum Ty2MultiFunctions {
___TOGETHER___ = 1,
___OTHER___ = 2
}
三,调用方案
①,回调
private onStandardCallback: ( tag: string, sender: any,...arg ) => void = (tag, sender, ...arg) => {
switch (tag) {
case `exe_complete`:
if( arg[0] == `Aonaufly` ){
console.log(`lkkkkkk : -> `);
}
break;
}
};
②,A,B,C,D方法
private doA( ): void{
console.log(`do a`);
}
private doB( a: number , b: number ): void{
console.log( `do b ${ a + b }` );
}
private async doC(): Promise<void>{
return new Promise<void>( resolve => {
egret.setTimeout( () => {
console.log(`do c`);
resolve();
} , this, 2000 );
} );
}
private async doD( a: number , b: number ): Promise<void>{
return new Promise<void>( resolve => {
egret.setTimeout( () => {
console.log(`do d ${a + b}`);
resolve();
} , this, 2000 );
} );
}
③调用
this.a = MultiFunctionsMgr.Instance.getExeFun(
`Aonaufly`,
Ty2MultiFunctions.___TOGETHER___,
[
{
exeFun: this.doA,
sender: this,
isPromise: false,
exeParams: null
},
{
exeFun: this.doB,
sender: this,
isPromise: false,
exeParams: [1,2]
},
{
exeFun: this.doC,
sender: this,
isPromise: true,
exeParams: null
},
{
exeFun: this.doD,
sender: this,
isPromise: true,
exeParams: [3,4]
}
],
this.onStandardCallback
);
this.a.startExe();
四,执行结果:
标签:方案,TypeScript,sender,list,tag,._,之多,exeParams,data 来源: https://blog.51cto.com/aonaufly/2524921