職責鏈模式閉包
使多個對象都有機會處理請求,從而避免請求的發送者和接受者之間的耦合關係,將對象連成一條鏈,並沿着這個鏈傳遞該請求,直到有一個對象處理它爲止app
請求發送者只須要知道鏈中的第一個節點,從而弱化了發送者和一組接受者之間的強聯繫異步
職責鏈模式使得程序中多了一些節點對象,在某次請求傳遞過程當中,大部分節點並無實質性做用,只是讓請求傳遞下去,從性能方面考慮,要避免過長的職責鏈帶來的性能耗損函數
商城作活動,預付定金500且購買的客戶可返現100,預付定金200且購買的客戶可返現50,普通購買則沒有返現且庫存不夠買不到。性能
//設置每一個節點的操做,即每種用戶對應的操做,若是不能該節點不能操做則傳遞給下一個節點。 var order500 = function (orderType, pay, stock) { if (orderType === 1 && pay === true) { console.log("100") } else { return 'nextSuccessor' } } var order200 = function (orderType, pay, stock) { if (orderType === 2 && pay === true) { console.log('50') } else { return 'nextSuccessor' } } var order = function (orderType, pay, stock) { if (stock > 0) { console.log('buy') } else { console.log('lack') } } //職責鏈,規定每一個節點的下一個節點,執行本節點的函數 function Chain(fn) { this.fn = fn this.nextSuccessor = null } Chain.prototype.setNextSuccessor = function (successor) { this.nextSuccessor = successor } Chain.prototype.passRequest = function () { var ret = this.fn.apply(this, arguments) if (ret === 'nextSuccessor') { return this.nextSuccessor && this.nextSuccessor.passRequest.apply(this.nextSuccessor, arguments) } } //把每一個節點都放到職責鏈中 var chainOrder500 = new Chain(order500) var chainOrder200 = new Chain(order200) var chainOrder = new Chain(order) //設置職責鏈的下一個節點 chainOrder500.setNextSuccessor(chainOrder200) chainOrder200.setNextSuccessor(chainOrder) //設定從某個職責鏈節點開始執行 chainOrder500.passRequest(1, true, 1)
//設置每一個節點的操做,即每種用戶對應的操做,若是不能該節點不能操做則傳遞給下一個節點。 var order500 = function (orderType, pay, stock) { if (orderType === 1 && pay === true) { console.log("100") } else { return 'nextSuccessor' } } var order200 = function (orderType, pay, stock) { var self = this setTimeout(function () { self.next() }, 1000) // if (orderType === 2 && pay === true) { // console.log('50') // } else { // return 'nextSuccessor' // } } var order = function (orderType, pay, stock) { if (stock > 0) { console.log('buy') } else { console.log('lack') } } //職責鏈,規定每一個節點的下一個節點,執行本節點的函數 function Chain(fn) { this.fn = fn this.nextSuccessor = null } Chain.prototype.setNextSuccessor = function (successor) { this.nextSuccessor = successor } Chain.prototype.passRequest = function () { var ret = this.fn.apply(this, arguments) if (ret === 'nextSuccessor') { return this.nextSuccessor && this.nextSuccessor.passRequest.apply(this.nextSuccessor, arguments) } } Chain.prototype.next = function () { return (this.nextSuccessor) && this.nextSuccessor.passRequest.apply(this.nextSuccessor, arguments) } // 把每一個節點都放到職責鏈中 var chainOrder500 = new Chain(order500) var chainOrder200 = new Chain(order200) var chainOrder = new Chain(order) //設置職責鏈的下一個節點 chainOrder500.setNextSuccessor(chainOrder200) chainOrder200.setNextSuccessor(chainOrder) // 設定從某個職責鏈節點開始執行 chainOrder500.passRequest(1, false, 1)
這裏須要增長一個next函數,手動傳遞到下一個節點。this
var order500 = function (orderType, pay, stock) { if (orderType === 1 && pay === true) { console.log("100") } else { return 'nextSuccessor' } } var order200 = function (orderType, pay, stock) { if (orderType === 2 && pay === true) { console.log('50') } else { return 'nextSuccessor' } } var order = function (orderType, pay, stock) { if (stock > 0) { console.log('buy') } else { console.log('lack') } } Function.prototype.after = function (fn) { var self = this return function () { var ret = self.apply(this, arguments) if (ret === 'nextSuccessor') { return fn && fn.apply(this, arguments) } return ret } } var func = order500.after(order200).after(order) func(1, true, 3)
這裏使用self變量存儲上一個函數,func存儲的是最後一個調用after返回的函數。一旦調用func函數,會先執行self保存的函數,會追根溯源一直到到最開始的self保存的函數order500。這裏利用了閉包的特性保留了每個self變量。整個函數的執行過程有點像倒序的遞歸。理解了過程也就會知道return ret這句代碼是爲後面的函數準備的~prototype
若是某塊功能中存在大量的if else能夠考慮使用職責鏈模式code