Javascript工作流引擎代碼及實例
最近在學(xué)習(xí)jBPM和Javascript,所以按照一些相關(guān)概念自己寫了下面的200行代碼的“工作流引擎”,工作流管理系統(tǒng)包含了流程定義,引擎,及應(yīng)用系統(tǒng)三個主要部分,下面的代碼實現(xiàn)了流程的分支合并,目前只支持一種環(huán)節(jié)上的遷移。拷貝到html,雙擊就可以跑起來。
var workflowDef = {
start:{
fn:"begin", //對應(yīng)處理方法可以在內(nèi)部定義,也可以在外部定義
next:["task1","task2"]
},
end:"end",
tasks:[{
id:"task1",
fn:function(){
alert("執(zhí)行任務(wù)一");
},
before:function(){
alert("執(zhí)行任務(wù)一前");
},
after:function(){
alert("執(zhí)行任務(wù)一后");
},
next:["task4","task5"]
},{
id:"task2",
fn:function(){
alert("執(zhí)行任務(wù)二");
},
before:function(){
alert("執(zhí)行任務(wù)二前");
},
after:function(){
alert("執(zhí)行任務(wù)二后");
},
next:["task3"]
},{
id:"task3",
fn:function(){
alert("執(zhí)行任務(wù)三");
},
before:function(){
alert("執(zhí)行任務(wù)三前");
},
after:function(){
alert("執(zhí)行任務(wù)三后");
},
//定義合并的數(shù)量
merge: 3,
next:"EOWF"
},{
id:"task4",
fn:function(){
alert("執(zhí)行任務(wù)四");
},
before:function(){
alert("執(zhí)行任務(wù)四前");
},
after:function(){
alert("執(zhí)行任務(wù)四后");
},
next:["task3"]
},{
id:"task5",
fn:function(){
alert("執(zhí)行任務(wù)五");
},
before:function(){
alert("執(zhí)行任務(wù)五前");
},
after:function(){
alert("執(zhí)行任務(wù)五后");
},
next:["task3"]
}]
}
start:{
fn:"begin", //對應(yīng)處理方法可以在內(nèi)部定義,也可以在外部定義
next:["task1","task2"]
},
end:"end",
tasks:[{
id:"task1",
fn:function(){
alert("執(zhí)行任務(wù)一");
},
before:function(){
alert("執(zhí)行任務(wù)一前");
},
after:function(){
alert("執(zhí)行任務(wù)一后");
},
next:["task4","task5"]
},{
id:"task2",
fn:function(){
alert("執(zhí)行任務(wù)二");
},
before:function(){
alert("執(zhí)行任務(wù)二前");
},
after:function(){
alert("執(zhí)行任務(wù)二后");
},
next:["task3"]
},{
id:"task3",
fn:function(){
alert("執(zhí)行任務(wù)三");
},
before:function(){
alert("執(zhí)行任務(wù)三前");
},
after:function(){
alert("執(zhí)行任務(wù)三后");
},
//定義合并的數(shù)量
merge: 3,
next:"EOWF"
},{
id:"task4",
fn:function(){
alert("執(zhí)行任務(wù)四");
},
before:function(){
alert("執(zhí)行任務(wù)四前");
},
after:function(){
alert("執(zhí)行任務(wù)四后");
},
next:["task3"]
},{
id:"task5",
fn:function(){
alert("執(zhí)行任務(wù)五");
},
before:function(){
alert("執(zhí)行任務(wù)五前");
},
after:function(){
alert("執(zhí)行任務(wù)五后");
},
next:["task3"]
}]
}
//////////定義引擎////////////
Yi = {};
Yi.Utils = {};
Yi.Utils.execute = function(o){
if(typeof o != 'function')
eval(o)();
else
o();
}
//工作流類
Yi.Workflow = function(workflowDef){
this.def = workflowDef;
this.tasks = this.def.tasks;
}
//public按照環(huán)節(jié)id查找查找
Yi.Workflow.prototype.findTask = function(taskId){
for(var i=0;i<this.tasks.length;i++){
if(this.tasks[i].id == taskId)
return this.tasks[i];
}
}
//public啟動工作流
Yi.Workflow.prototype.start = function(){
this.currentTasks = [];
Yi.Utils.execute(this.def.start.fn);
for(var i=0;i<this.def.start.next.length;i++){
this.currentTasks[i] = this.findTask(this.def.start.next[i]);
Yi.Utils.execute(this.currentTasks[i].before);
}
}
//private
Yi.Workflow.prototype.findCurrentTaskById = function(taskId){
for(var i=0;i<this.currentTasks.length;i++){
if(this.currentTasks[i].id == taskId)
return this.currentTasks[i];
}
return null;
}
//private
Yi.Workflow.prototype.removeFromCurrentTasks = function(task){
var temp = [];
for(var i=0;i<this.currentTasks.length;i++){
if(!(this.currentTasks[i] == task))
temp.push(this.currentTasks[i]);
}
this.currentTasks = temp;
temp = null;
}
//public觸發(fā)當前環(huán)節(jié)
Yi.Workflow.prototype.signal = function(taskId){
//只處理當前活動環(huán)節(jié)
var task = this.findCurrentTaskById(taskId);
if(task == null){
alert("工作流未流轉(zhuǎn)到此環(huán)節(jié)!");
return;
}
//對于合并的處理
if(task.merge != undefined){
if(task.merge != 0){
alert("工作流流轉(zhuǎn)條件不充分!");
return;
}else{
Yi.Utils.execute(task.before);
}
}
//觸發(fā)當前環(huán)節(jié)
Yi.Utils.execute(task.fn);
//觸發(fā)后動作
Yi.Utils.execute(task.after);
//下一步如果工作流結(jié)束
if(task.next === "EOWF"){
Yi.Utils.execute(this.def.end);
delete this.currentTasks;
return;
}
//遍歷下一步環(huán)節(jié)
this.removeFromCurrentTasks(task);
for(var i=0;i<task.next.length;i++){
var tempTask = this.findTask(task.next[i]);
if(!tempTask.inCurrentTasks)
this.currentTasks.push(tempTask);
if(tempTask.merge != undefined){
tempTask.merge--;
tempTask.inCurrentTasks = true;
}
else
Yi.Utils.execute(tempTask.before);
}
}
//public獲取當前的活動環(huán)節(jié)
Yi.Workflow.prototype.getCurrentTasks = function(){
return this.currentTasks;
}
//public獲取流程定義
Yi.Workflow.prototype.getDef = function(){
return this.def;
}
Yi = {};
Yi.Utils = {};
Yi.Utils.execute = function(o){
if(typeof o != 'function')
eval(o)();
else
o();
}
//工作流類
Yi.Workflow = function(workflowDef){
this.def = workflowDef;
this.tasks = this.def.tasks;
}
//public按照環(huán)節(jié)id查找查找
Yi.Workflow.prototype.findTask = function(taskId){
for(var i=0;i<this.tasks.length;i++){
if(this.tasks[i].id == taskId)
return this.tasks[i];
}
}
//public啟動工作流
Yi.Workflow.prototype.start = function(){
this.currentTasks = [];
Yi.Utils.execute(this.def.start.fn);
for(var i=0;i<this.def.start.next.length;i++){
this.currentTasks[i] = this.findTask(this.def.start.next[i]);
Yi.Utils.execute(this.currentTasks[i].before);
}
}
//private
Yi.Workflow.prototype.findCurrentTaskById = function(taskId){
for(var i=0;i<this.currentTasks.length;i++){
if(this.currentTasks[i].id == taskId)
return this.currentTasks[i];
}
return null;
}
//private
Yi.Workflow.prototype.removeFromCurrentTasks = function(task){
var temp = [];
for(var i=0;i<this.currentTasks.length;i++){
if(!(this.currentTasks[i] == task))
temp.push(this.currentTasks[i]);
}
this.currentTasks = temp;
temp = null;
}
//public觸發(fā)當前環(huán)節(jié)
Yi.Workflow.prototype.signal = function(taskId){
//只處理當前活動環(huán)節(jié)
var task = this.findCurrentTaskById(taskId);
if(task == null){
alert("工作流未流轉(zhuǎn)到此環(huán)節(jié)!");
return;
}
//對于合并的處理
if(task.merge != undefined){
if(task.merge != 0){
alert("工作流流轉(zhuǎn)條件不充分!");
return;
}else{
Yi.Utils.execute(task.before);
}
}
//觸發(fā)當前環(huán)節(jié)
Yi.Utils.execute(task.fn);
//觸發(fā)后動作
Yi.Utils.execute(task.after);
//下一步如果工作流結(jié)束
if(task.next === "EOWF"){
Yi.Utils.execute(this.def.end);
delete this.currentTasks;
return;
}
//遍歷下一步環(huán)節(jié)
this.removeFromCurrentTasks(task);
for(var i=0;i<task.next.length;i++){
var tempTask = this.findTask(task.next[i]);
if(!tempTask.inCurrentTasks)
this.currentTasks.push(tempTask);
if(tempTask.merge != undefined){
tempTask.merge--;
tempTask.inCurrentTasks = true;
}
else
Yi.Utils.execute(tempTask.before);
}
}
//public獲取當前的活動環(huán)節(jié)
Yi.Workflow.prototype.getCurrentTasks = function(){
return this.currentTasks;
}
//public獲取流程定義
Yi.Workflow.prototype.getDef = function(){
return this.def;
}
////////應(yīng)用系統(tǒng)///////////////
var wf = new Yi.Workflow(workflowDef);
alert("啟動工作流");
wf.start();
alert("嘗試手工執(zhí)行任務(wù)3,返回工作流沒有流轉(zhuǎn)到這里");
wf.signal("task3");
alert("分支開始");
alert("手工執(zhí)行任務(wù)1");
wf.signal("task1");
alert("手工執(zhí)行任務(wù)2");
wf.signal("task2");
alert("手工執(zhí)行任務(wù)4");
wf.signal("task4");
alert("手工執(zhí)行任務(wù)5");
wf.signal("task5");
alert("手工執(zhí)行任務(wù)3");
wf.signal("task3");
function begin(){
alert("流程開始,該函數(shù)在外部定義");
}
function end(){
alert("流程結(jié)束");
}
var wf = new Yi.Workflow(workflowDef);
alert("啟動工作流");
wf.start();
alert("嘗試手工執(zhí)行任務(wù)3,返回工作流沒有流轉(zhuǎn)到這里");
wf.signal("task3");
alert("分支開始");
alert("手工執(zhí)行任務(wù)1");
wf.signal("task1");
alert("手工執(zhí)行任務(wù)2");
wf.signal("task2");
alert("手工執(zhí)行任務(wù)4");
wf.signal("task4");
alert("手工執(zhí)行任務(wù)5");
wf.signal("task5");
alert("手工執(zhí)行任務(wù)3");
wf.signal("task3");
function begin(){
alert("流程開始,該函數(shù)在外部定義");
}
function end(){
alert("流程結(jié)束");
}
@2008 楊一. 版權(quán)所有. 保留所有權(quán)利
posted on 2009-03-06 17:39 楊一 閱讀(2009) 評論(1) 編輯 收藏 所屬分類: Other Tech