近期遇到很多js脚本流程调整的问题,觉得这方面薄弱,
所以,自己先写一个简单的协调类来试行一下。
下面行一只是传递第一个函数的参数,
第二行则是组织与调用整个流程,参数一流程正常顺序,参数二则是所有子流程函数对应的实际函数,以及一些特殊的流程内跳转。
funFlow.arg = money;
funFlow.call( 'buy,money,service',{add:["f0"],buy:["f1"],money:["f2",{notenough:'add,money'}],service:["f3"]} );
例子是买一个商品,设定手头上的钱,商品的价钱,以及银行有的钱,再写了四个函数进行相应的操作。
函数f0是到银行取钱,f1是购买商品的行为,f2是进行价钱的确认与交付,f3是确认购买。
var funFlow={
flow:null,struct:null,
flowList:[], flowLog:'|', args:{}, arg:null,
get_flowList:function(i){
i = i || -1;
i = i < 0 ? this.flowList.length + i : i;
if( i < 0 || i >= this.flowList.length )
return null;
else
return this.flowList[i];
},
logIn:function(log){
if( this.flowLog.indexOf('|'+log+'|') > -1 )
return true;
else {
return false;
}
},
logAdd:function(log){
if( !this.logIn(log) )
this.flowLog += log+'|';
},
logDel:function(log){
if( this.logIn(log) ){
this.flowLog.replace(log+"|", "");
return true;
}else{
return false;
}
},
call:function(flow, struct) {
funFlow.flow = flow.split(',');
funFlow.struct = struct;
funFlow.next();
},
next:function(){
var g=funFlow, flow=g.flow, struct=g.struct;
if( flow.length == 0 )
return false;
var i,arg;
var prevHand=null, ret=null;
while(true){
if (ret != null && ret != 'END') {
flow = struct[prevHand][1][ret].split(',').concat( flow );
}
prevHand = flow.shift();
arg=g.arg;g.arg=null;
ret = window[struct[prevHand][0]]( arg );
//如果需要等待用户响应,也可以输出END强制停止,待确认后再执行next函数
if( flow.length == 0 || ret == 'END' ){
g.flow = flow;
return true;
}
//记录当前子流程标识。
g.flowList.push(prevHand);
}
}
};
var money = 100; //物品价格
var readyMoney = 80; //身上带有的钱
var bankMoney = 200; //银行有钱
//可在一次性参数池中传递参数
funFlow.arg = money;
funFlow.call( 'buy,money,service',{add:["f0"],buy:["f1"],money:["f2",{notenough:'add,money'}],service:["f3"]} );
function f0(addMoney) {
alert(' get ' + addMoney + ' from bank');
if( bankMoney >= addMoney ){
readyMoney += addMoney;
bankMoney -= addMoney;
}else{
alert(' not enough money in the bank ');
return 'END';
}
}
function f1( productMoney ) {
//可在共享参数池中传递参数
funFlow.args.pm = productMoney;
alert(' f1 money = '+ productMoney );
}
function f2() {
if (readyMoney >= funFlow.args.pm){
alert('f2, buy it, click the window confirm it. ');
if( window.addEventListener ){
document.addEventListener ("click", funFlow.next);
}else if( window.attachEvent ){
document.attachEvent ("onclick", funFlow.next);
}
return 'END';
} else {
funFlow.arg = funFlow.args.pm - readyMoney;
alert('f2, not enough money '+funFlow.arg);
return 'notenough';
}
}
function f3() {
alert(' f3 ');
}