Hi大家好,今天第13天了,Triskaidekaphobia 不知道打什麼只好玩個冷知識關鍵字XD
好,接續上一篇。上一篇其實在設定下一節點的時候也可以這樣用,這樣看起更有鏈狀感
chainOrder500.setNextStage(chainOrder200).setNextStage(chainOrderNormal);
那如果有些方法是非同步的(例如ajax請求),我們原本返回的nextStage字串就已經無法滿足現況了,我們現在新增一個next方法,讓這些非同步請求的方法在可以進入下一節點的時候自行呼叫使用
Chain.prototype.next = function () {
return this.stage && this.stage.passRequest.apply(this.stage, arguments);
};
let's try it
var fn1 = new Chain(function () {
console.log('1');
return 'nextStage';
});
var fn2 = new Chain(function () {
var self = this;
setTimeout(function () {
console.log('2');
self.next();
}, 3000);
});
var fn3 = new Chain(function () {
console.log('3');
});
fn1.setNextStage(fn2).setNextStage(fn3);
fn1.passRequest();
職責鏈的最大優點是可以將所有節點解藕,無論誰是請求者誰是接收者,在鏈結中可以任意的拆解或是新增節點,工程師也不必在意每個節點實際要做的內容,更可以手動指定起始節點,假設我們今天客戶流程更改,我們就只需要更改鏈結內節點順序就好。
但這樣的模式仍然有些缺點,首先是我們沒辦法保證請求一定會被處理,過程中的節點可能都會直接跳過這個請求,為避免這狀況發生,我們可以在鏈尾增加一個處理這種狀況的節點。另外一點也要注意的是,也許某些請求中大部分的節點都只是傳遞至下一節點的功能而已,從效能方面考量我們要避免過長的職責鏈所帶來的效能耗損。
在JS中有更容易更簡單做到職責鏈的方法,我們可以直接新增Function的類別函數,我們在這邊先叫此方法為after,實作上就是帶入下一個要執行的函數然後讓他執行,就這麼簡單,但一樣要先約定好執行下一個節點的方法,
在這裡我們一樣用回傳'nextStage'字串來表示
Function.prototype.after = function (fn) {
var self = this;
return function () {
var ret = self.apply(this, arguments);
if (ret === 'nextStage') {
return fn.apply(this, arguments);
}
return ret;
};
};
var order = order500.after(order200).after(orderNormal);
order(1, true, 10);
最後,我們在Day4文章迭代器模式中,我們有做一個迭代器來執行獲取上傳物件的方法,大致的code長這樣:
var iteratorUploadObj = function () {
for (var i = 0, fn; fn = arguments[i++];) {
var uploadObj = fn();
if (uploadObj !== false) {
return uploadObj;
}
}
};
var getUploadObjA = function () {
//A方法實作內容
};
var getUploadObjB = function () {
//B方法實作內容
};
var uploadObj = iteratorUploadObj(getUploadObjA, getUploadObjB);
在這裡我們就可以利用職責鏈模式直接讓這些方法直接接下去執行,不必要再多做個迭代器,要注意記得每個方法要回傳'nextStage'
var getUploadObjA = function () {
//A方法實作內容
return 'nextStage';
};
var getUploadObjB = function () {
//B方法實作內容
return 'nextStage';
};
var uploadObj = getUploadObjA.after(getUploadObjB);
其實職責鏈模式很常在不知不覺中被使用到,像是JS的原型鏈就有類似職責鏈模式的行為。
好,以上就是職責鏈模式。