這裏有一份簡潔的前端知識體系等待你查收,看看吧,會有驚喜哦~若是以爲不錯,懇求star哈~前端
職責連是由多個不一樣的對象組成的,有發送者跟接收者,分別負責信息的發送跟接收,其中,鏈中第一個對象是 職責連是由多個不一樣的對象組成的,發送者是發送請求的對象,接收者接收請求而且對其進行處理或傳遞的對象。基本流程以下:git
職責鏈模式是個鏈式結構,請求在鏈中的節點之間依次傳遞,直到有一個對象能處理該請求爲止。若是沒有任何對象處理該請求的話,那麼請求就會從鏈中離開。github
以電商網站抽獎爲例,規則以下:ajax
首先須要定義幾個字段:bash
實現以下:app
var order = function(orderType,isPay,count) {
if(orderType == 1) { // 用戶充值500元
if(isPay == true) { // 若是充值成功的話,100%中獎
console.log("親愛的用戶,您中獎了100元紅包了");
}else {
// 充值失敗,就看成普通用戶來處理中獎信息
if(count > 0) {
console.log("親愛的用戶,您已抽到10元優惠卷");
}else {
console.log("親愛的用戶,請再接再礪哦");
}
}
}else if(orderType == 2) { // 用戶充值200元
if(isPay == true) { // 若是充值成功的話,100%中獎
console.log("親愛的用戶,您中獎了20元紅包了");
}else {
// 充值失敗,就看成普通用戶來處理中獎信息
if(count > 0) {
console.log("親愛的用戶,您已抽到10元優惠卷");
}else {
console.log("親愛的用戶,請再接再礪哦");
}
}
}else if(orderType == 3) {
// 普通用戶來處理中獎信息
if(count > 0) {
console.log("親愛的用戶,您已抽到10元優惠卷");
}else {
console.log("親愛的用戶,請再接再礪哦");
}
}
};
複製代碼
如上代碼,雖然實現了需求,但存在的問題也比較突出: 1、業務邏輯代碼耦合度過高,若是想增長條件,好比充值300能夠中獎150元紅包,這時候就很容易改出問題 2、冗餘代碼太多,普通用戶抽獎的代碼是能夠單獨抽離出來的異步
function order500(orderType,isPay,count){
if(orderType == 1 && isPay == true) {
console.log("親愛的用戶,您中獎了100元紅包了");
}else {
//我不知道下一個節點是誰,反正把請求日後面傳遞
return "nextSuccessor";
}
};
function order200(orderType,isPay,count) {
if(orderType == 2 && isPay == true) {
console.log("親愛的用戶,您中獎了20元紅包了");
}else {
//我不知道下一個節點是誰,反正把請求日後面傳遞
return "nextSuccessor";
}
};
function orderNormal(orderType,isPay,count){
// 普通用戶來處理中獎信息
if(count > 0) {
console.log("親愛的用戶,您已抽到10元優惠卷");
}else {
console.log("親愛的用戶,請再接再礪哦");
}
}
// 下面須要編寫職責鏈模式的封裝構造函數方法
var Chain = function(fn){
this.fn = fn;
this.successor = null;
};
Chain.prototype.setNextSuccessor = function(successor){
return this.successor = successor;
}
// 把請求往下傳遞
Chain.prototype.passRequest = function(){
var ret = this.fn.apply(this,arguments);
if(ret === 'nextSuccessor') {
return this.successor && this.successor.passRequest.apply(this.successor,arguments);
}
return ret;
}
//如今咱們把3個函數分別包裝成職責鏈節點:
var chainOrder500 = new Chain(order500);
var chainOrder200 = new Chain(order200);
var chainOrderNormal = new Chain(orderNormal);
// 而後指定節點在職責鏈中的順序
chainOrder500.setNextSuccessor(chainOrder200);
chainOrder200.setNextSuccessor(chainOrderNormal);
//最後把請求傳遞給第一個節點:
chainOrder500.passRequest(1,true,500); // 親愛的用戶,您中獎了100元紅包了
chainOrder500.passRequest(2,true,500); // 親愛的用戶,您中獎了20元紅包了
chainOrder500.passRequest(3,true,500); // 親愛的用戶,您已抽到10元優惠卷
chainOrder500.passRequest(1,false,0); // 親愛的用戶,請再接再礪哦
複製代碼
如上代碼: 1、分別編寫order500,order200,orderNormal三個函數,處理本身的業務邏輯,若是本身的函數不能處理的話,就返回字符串nextSuccessor 日後面傳遞 2、封裝Chain構造函數,接收fn作爲參數,且帶有屬性successor。實例化後的Chain類型的對象,就像一個一個獨立存在的節點。 3、Chain構造函數原型上有2個方法,分別是setNextSuccessor 和 passRequest。setNextSuccessor 方法指定了節點在職責鏈中的順序,passRequest方法是將請求轉移到職責鏈的下一個節點。函數
如上文提到的,假設須要實現「充值300中獎150元」,咱們能夠編寫order300這個函數,經過Chain包裝起來,指定在職責鏈中的順序便可。業務邏輯的代碼不須要任何處理。性能
如今又有一個問題,咱們在開發中常常會碰到ajax異步請求,若是咱們用上面的作法,就不生效了。由此,便引出了異步的職責鏈來解決這個問題。咱們給Chain類再增長一個原型方法Chain.prototype.next,表示手動傳遞請求給職責鏈中的一下個節點。網站
function Fn1() {
console.log(1);
return "nextSuccessor";
}
function Fn2() {
console.log(2);
var self = this;
setTimeout(function(){
self.next();
},1000);
}
function Fn3() {
console.log(3);
}
// 下面須要編寫職責鏈模式的封裝構造函數方法
var Chain = function(fn){
this.fn = fn;
this.successor = null;
};
Chain.prototype.setNextSuccessor = function(successor){
return this.successor = successor;
}
// 把請求往下傳遞
Chain.prototype.passRequest = function(){
var ret = this.fn.apply(this,arguments);
if(ret === 'nextSuccessor') {
return this.successor && this.successor.passRequest.apply(this.successor,arguments);
}
return ret;
}
Chain.prototype.next = function(){
return this.successor && this.successor.passRequest.apply(this.successor,arguments);
}
//如今咱們把3個函數分別包裝成職責鏈節點:
var chainFn1 = new Chain(Fn1);
var chainFn2 = new Chain(Fn2);
var chainFn3 = new Chain(Fn3);
// 而後指定節點在職責鏈中的順序
chainFn1.setNextSuccessor(chainFn2);
chainFn2.setNextSuccessor(chainFn3);
chainFn1.passRequest(); // 打印出1,2 過1秒後 會打印出3
複製代碼
如上代碼,當執行到F2時,遇到了定時器異步函數,當定時器執行結束後,調用了next方法,手動將請求交給職責鏈中的下一個節點,所以過了一秒後,會打印3。
職責鏈模式中多了一點節點對象,可能在某一次請求過程當中,大部分節點沒有起到實質性做用,他們的做用只是讓請求傳遞下去,從性能方面考慮,避免過長的職責鏈提升性能。