利用async.auto实现 可配置同步异步嵌套方法调用工作流
首先了解async.auto原理
1.async.auto普通版用法:
下面的oneLoad twoLoad threeLoad方法会同步执行 但是会等所有方法的回调回来后,才会到async.auto complete方法
async.auto(
{
oneLoad: (oneLoadFinish) => {
this.func1(oneLoadFinish);
},
twoLoad: (twoLoadFinish) => {
this.func2(twoLoadFinish);
},
threeLoad: (threeLoadFinish) => {
this.func3(threeLoadFinish);
},
}, (err) => {
if (err) {
console.warn(err)
} else {
console.log('async.auto complete')
}
}
);
2.async.auto进阶版用法
参考大神链接:https://blog.csdn.net/puncha/article/details/9236275
async.auto接受一个对象,即键值对,其每一个属性,就是一个你要执行的函数逻辑,而依赖关系通过属性名指定。
async.auto({
func1: function (callback, results) {
callback(null, "xxx");
},
func2: function (callback, results) {
callback(null, {});
},
func3: ["func2", function (callback, results) {
callback(null, 3);
}],
func4: ["func1", "func3", function (callback, results) {
callback(null);
}]
});
上面代码的意思是,func1和func2相互独立,没有依赖,func3依赖于func2,func4依赖于func1,func3(其实也间接依赖于func2)。
如果不用async.auto的话,差不多这样吧:
async.parallel([
this.func1(),
async.waterfall([
this.func2(),
this.func3()
]),
], this.func4())
3.下面是利用async.auto实现 可配置同步异步嵌套方法调用工作流
其实就是写一个方法 还原包含方法键值对的对象
//调用的方法名和方法的参数
export class ProcessBaseVO {
public funcName: string;
public args: any = null;
};
/**
* 获取auto对象方法
* (async.auto接受一个对象,即键值对,其每一个属性,就是一个你要执行的函数逻辑,而依赖关系通过属性名指定)
*/
export function getSectionControlProcessList(runList: ProcessBaseVO[][], playground: any): object {
let ret: Object = {};
let relyOnFuncList: string[] = [];//依赖函数名数组
lodash.forEach(
runList,
(oneProcess: ProcessBaseVO[]) => {
//二维数组每一项
//这里有三项:
//[{ funcName: 'func1', 'args': null }]
//[{ funcName: 'func2', 'args': null }, { funcName: 'func3', 'args': null }]
//[{ funcName: 'func4', 'args': null }]
lodash.forEach(
oneProcess,
(vo: ProcessBaseVO) => {
//此级别为同步执行函数
let key = vo.funcName;
ret[key] = []; //ret.func1 = []
if (relyOnFuncList.length <= 0) {
if (vo.args == null) {
ret[key].push(
(finish) => {
playground[key](finish);
}
);
//1. ret.func1 = [(finish)=>{playground.func1(finish)}]
} else {
//有自定义传参
ret[key].push(
(finish) => {
playground[key](vo.args, finish);
}
);
}
} else {
lodash.forEach(
relyOnFuncList,
(value: string) => {
ret[key].push(value);
//3. ret.func2 = ["func1"]
//4. ret.func3 = ["func1"]
//8. ret.func4 = ["func1","func2","func3"]
}
);
if (vo.args == null) {
ret[key].push(
(results, finish) => {
playground[key](finish);
}
);
//4. ret.func2 = ["func1",(results, finish)=>{playground.func2(finish)}]
//5. ret.func3 = ["func1",(results, finish)=>{playground.func3(finish)}]
//9. ret.func4 = ["func1","func2","func3",(results, finish)=>{playground.func4(finish)}]
} else {
//有自定义传参
ret[key].push(
(results, finish) => {
playground[key](vo.args, finish);
}
);
}
}
}
);
lodash.forEach(
oneProcess,
(vo: ProcessBaseVO) => {
//放入依赖函数名
relyOnFuncList.push(vo.funcName);
//2. relyOnFuncList = ["func1"]
//6. relyOnFuncList = ["func1","func2"]
//7. relyOnFuncList = ["func1","func2","func3"]
//10. relyOnFuncList = ["func1","func2","func3","func4"]
}
);
}
);
return ret;
}
//test 模拟配置
export const PROCESS_LIST: ProcessBaseVO[][] = [
[{ funcName: 'func1', 'args': null }],
[{ funcName: 'func2', 'args': null }, { funcName: 'func3', 'args': null }],
[{ funcName: 'func4', 'args': null }]
];
//方法使用:传入自定义PROCESS_LIST 返回一个对象
console.log(this.getSectionControlProcessList(PROCESS_LIST, this));
//返回结果
/**
* 以所有方法都没有传参举例:
* ret = {
func1: [(finish) => { playground.func1(finish) }],
func2: ["func1", (results, finish) => { playground.func2(finish) }],
func3: ["func1", (results, finish) => { playground.func3(finish) }],
func4: ["func1", "func2", "func3", (results, finish) => { playground.func4(finish) }]
* }
* func1独立,func2和func3依赖func1执行完,func4依赖func1 func2 func3执行完毕
*/