一個只有99行代碼的JS流程框架(二)

導語

前面寫了一篇文章,叫《一個只有99行代碼的JS流程框架》,雖然該框架基本已經能實現一個流程正常的邏輯流轉,可是在分模塊應用下仍是缺乏必定的能力,沒法將一個頁面中的不一樣模塊很好的鏈接在一塊兒,因而對以前的框架進行了升級,新增了子流程的概念。框架

子流程

什麼是子流程?在這個升級後的框架裏(固然代碼已經不止99行了,不要在意標題),每一個步驟不但能夠是一個function,還能夠引用另外一個流程,這個被引用的流程就叫子流程。先看個簡單的例子:學習

flowJS({
    init:function(){
        this.setNext('步驟A').setNext('步驟B').setNext('步驟C');
        this.next();
    },
    '步驟A':function(){
        this.next();
    },
    '步驟B':{
    init:function(){
        this.setNext('子步驟B1').setNext('子步驟B2').setNext('子步驟B3');
        this.next();
        },
        '子步驟B1':function(){
        this.next();
        },
        '子步驟B2':function(){
            this.next();
        },
        '子步驟B3':function(){
        this.parent.next();
    }
    },
    '步驟C':function(){
        console.log('執行 步驟C');
    console.log('當前流程運行的軌跡:');
    console.log(flowJS.trace);
    }
});

上面這個例子中,步驟B對應的對象就是子流程。this

還能夠有另外一種寫法,也是對分模塊應用的更好的實現:spa

/*定義子流程*/
flowJS('子流程B', {
    init:function(){
        this.setNext('子步驟B1').setNext('子步驟B2').setNext('子步驟B3');
        this.next();
    },
    '子步驟B1':function(){
        this.next();
    },
    '子步驟B2':function(){
        this.next();
    },
    '子步驟B3':function(){
        this.parent.next();
    }
});
/*父流程*/
flowJS({
    init:function(){
        this.setNext('步驟A').setNext('步驟B').setNext('步驟C');
        this.next();
    },
    '步驟A':function(){
        this.next();
    },
    '步驟B':'子流程B',
    '步驟C':function(){
        console.log('執行 步驟C');
    console.log('當前流程運行的軌跡:');
    console.log(flowJS.trace);
    }
});

能夠看到,父流程的 步驟B 引用了前面定義的 子流程B,這樣對於一些公共的流程邏輯就能夠單獨抽取出去做爲子流程,被其餘父流程引用。而子流程與父流程的交互,咱們能夠在代碼中經過 this.parent 來實現。3d

在子流程的每一步中均可以獲取 this.parent,獲得的是當前子流程對應的步驟,這個步驟跟其餘步驟同樣也具備一樣的API(詳見上一篇文章《一個只有99行代碼的JS流程框架》對步驟API的介紹)。code

另外,須要說明的一點:此次的升級,並無對流程步驟的API作改變,僅僅是引入了子流程的使用方式,其實就是定義子流程,而後引用子流程,接着就是父流程和子流程之間的交互。對象

一樣,按照規矩,貼上code(例子的序號接上前篇文章的序號,從10開始)blog

最簡單的子流程使用方法

flowJS({
    init:function(){
    console.log('執行 init');
        this.setNext('步驟A').setNext('步驟B').setNext('步驟C');
        this.next();
    },
    '步驟A':function(){
        console.log('執行 步驟A');
        this.next();
    },
    '步驟B':{
    init:function(){
        console.log('執行 子步驟B init');
        this.setNext('子步驟B1').setNext('子步驟B2').setNext('子步驟B3');
        this.next();
        },
        '子步驟B1':function(){
            console.log('執行 子步驟B1');
            this.next();
        },
        '子步驟B2':function(){
            console.log('執行 子步驟B2');
            console.log('上一步 :'+this.getPrev()); //打印:子步驟B1
            console.log('當前步 :'+this.getCurr()); //打印:子步驟B2
        console.log('下一步 :'+this.getNext()); //打印:子步驟B3
        this.next();
        },
        '子步驟B3':function(){
            console.log('執行 子步驟B3');
            this.parent.next();
        }
    },
    '步驟C':function(){
        console.log('執行 步驟C');
    console.log('當前流程運行的軌跡:');
    console.log(flowJS.trace);
    }
});

執行結果:get

子流程和父流程 經過 this.parent 進行交互

flowJS({
    init:function(){
    console.log('執行 init');
        this.setNext('步驟A').setNext('步驟B').setNext('步驟C');
        this.next();
    },
    '步驟A':function(){
        console.log('執行 步驟A');
    this.nextData({name1:'value1'});
    this.flowData({name2:'value2'});
        this.next();
    },
    '步驟B':{
    init:function(){
        console.log('執行 子步驟B init');
        this.setNext('子步驟B1').setNext('子步驟B2').setNext('子步驟B3');
        this.next();
    },
    '子步驟B1':function(){
        console.log('執行 子步驟B1');
        this.nextData({name3:'value3'});
        this.flowData({name4:'value4'});
        this.next();
    },
    '子步驟B2':function(){
        console.log('執行 子步驟B2');
        console.log('父步驟的上一步 :'+this.parent.getPrev());//打印:步驟A
        console.log('父步驟的步驟名 :'+this.parent.getCurr());//打印:步驟B
        console.log('父步驟的下一步 :'+this.parent.getNext());//打印:步驟C
        console.log('父步驟的數據:');
        console.log(this.parent.stepData());//打印:Object {name1: "value1"}
        console.log(this.parent.flowData());//打印:Object {name2: "value2"}
        console.log('上一步 :'+this.getPrev());//打印:子步驟B1
        console.log('當前步 :'+this.getCurr());//打印:子步驟B2
        console.log('下一步 :'+this.getNext());//打印:子步驟B3
        console.log('當前步的數據:');
        console.log(this.stepData());//打印:Object {name3: "value3"}
        console.log(this.flowData());//打印:Object {name4: "value4"}
        this.next();
    },
    '子步驟B3':function(){
        console.log('執行 子步驟B3');
        this.parent.nextData({name5:'value5'});
        this.parent.flowData({name6:'value6'});
        this.parent.next();
    }
    },
    '步驟C':function(){
        console.log('執行 步驟C');
    console.log(this.stepData());//打印:Object {name5: "value5"}
    console.log(this.flowData());//打印:Object {name2: "value2", name6: "value6"}
    console.log('當前流程運行的軌跡:');
    console.log(flowJS.trace);
    }
});

執行結果:源碼

多個子流程並行執行

flowJS({
    init:function(){
    console.log('執行 init');
        this.setNext('步驟A').setNext(['步驟B', '步驟C']).setNext('步驟D');
        this.next();
    },
    '步驟A':function(){
        console.log('執行 步驟A');
        this.next();
    },
    '步驟B':{
    init:function(){
        console.log('執行 子步驟B init');
        this.setNext('子步驟B1').setNext('子步驟B2').setNext('子步驟B3');
        this.next();
        },
        '子步驟B1':function(){
        console.log('執行 子步驟B1');
        this.next();
    },
    '子步驟B2':function(){
        console.log('執行 子步驟B2');
        this.next();
    },
    '子步驟B3':function(){
        var self = this;
            //這裏打印的時間和 子步驟C3 的時間同樣
        console.log('執行 子步驟B3 時間:' + new Date().getSeconds());
        setTimeout(function(){
            self.parent.next();
        }, 2000);
    }
    },
    '步驟C':{
    init:function(){
        console.log('執行 子步驟C init');
        this.setNext('子步驟C1').setNext('子步驟C2').setNext('子步驟C3');
        this.next();
    },
        '子步驟C1':function(){
        console.log('執行 子步驟C1');
        this.next();
    },
    '子步驟C2':function(){
        console.log('執行 子步驟C2');
        this.next();
    },
    '子步驟C3':function(){
        var self = this;
            //這裏打印的時間和 子步驟B3 的時間同樣
        console.log('執行 子步驟C3 時間:' + new Date().getSeconds());
        setTimeout(function(){
            self.parent.next();
        }, 2000);
    }
    },
    '步驟D':function(){
        //這裏打印的時間比上面的子流程的時間晚2秒,由於兩個子流程是並行執行的
        console.log('執行 步驟D 時間:' + new Date().getSeconds());
    console.log('當前流程運行的軌跡:');
    console.log(flowJS.trace);
    }
});

執行結果:

定義子流程和引用子流程

flowJS('子流程A', {
    init:function(){
        this.next('子步驟A1');
    },
    '子步驟A1':function(){
        console.log('執行 子步驟A1');
        console.log('當前步驟:'+this.getCurr());//打印:子步驟A1
        console.log('父步驟:'+this.parent.getCurr());//打印:步驟A
        this.parent.next();
    }
});
flowJS('子流程B', {
    init:function(){
        console.log('執行 子步驟B init');
        this.setNext('子步驟B1').setNext('子步驟B2').setNext('子步驟B3');
        this.next();
    },
    '子步驟B1':function(){
        console.log('執行 子步驟B1');
        this.next();
    },
    '子步驟B2':function(){
        console.log('執行 子步驟B2');
        this.next();
    },
    '子步驟B3':function(){
        console.log('執行 子步驟B3');
        console.log('當前步驟:'+this.getCurr());//打印:子步驟B3
        console.log('父步驟:'+this.parent.getCurr());//打印:步驟B
        this.parent.next();
    }
});
flowJS('子流程C', {
    init:function(){
        console.log('執行 子步驟C init');
        this.setNext('子步驟C1').setNext('子步驟C2').setNext('子步驟C3');
        this.next();
    },
    '子步驟C1':function(){
        console.log('執行 子步驟C1');
        this.next();
    },
    '子步驟C2':function(){
        console.log('執行 子步驟C2');
        this.next();
    },
    '子步驟C3':function(){
        console.log('執行 子步驟C3');
        console.log('當前步驟:'+this.getCurr());//打印:子步驟C3
        console.log('父步驟:'+this.parent.getCurr());//打印:步驟C
        this.parent.next();
    }
});
flowJS({
    init:function(){
    console.log('執行 init');
        this.setNext('步驟A').setNext(['步驟B', '步驟C']).setNext('步驟D');
        this.next();
    },
    '步驟A':'子流程A',
    '步驟B':'子流程B',
    '步驟C':'子流程C',
    '步驟D':function(){
    console.log('當前流程運行的軌跡:');
    console.log(flowJS.trace);
    }
});

執行結果:

從上面幾個例子能夠看到,子流程和父流程之間的信息交互很是簡單,其實就是經過this.parent來獲取到父步驟,經過父步驟來獲取和傳遞數據,所以也能讓這個流程框架擁有更大能力來適應更多的應用場景。

爲了方便交流學習,上面例子完整代碼可經過附件下載,最後一樣貼上框架源碼:

此文已由做者受權騰訊雲技術社區發佈,轉載請註明文章出處

相關文章
相關標籤/搜索