中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

javascript職責鏈模式的代碼怎么寫

發布時間:2022-02-22 17:22:00 來源:億速云 閱讀:121 作者:iii 欄目:開發技術

這篇“javascript職責鏈模式的代碼怎么寫”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“javascript職責鏈模式的代碼怎么寫”文章吧。

職責鏈的定義:使多個對象都有機會處理請求,從而避免請求的發送者和接收者之間的耦合關系,將這些對象連成一條鏈,并沿著這條鏈傳遞該請求,直到有一個對象能處理它為止,傳遞鏈中的這些對象就叫節點。

需求背景: 一個電商網站,用戶交500定金且定金已付時,可享受500優惠券且不受貨物數量限制;用戶交200定金且定金已付時,可享受500優惠券且不受貨物數量限制;用戶不交定金時受貨物數量限制,有貨時原價買,無貨時則無法買。

原始版本, if else一路判斷

var buyOrder = function(orederType, pay, stock){
    if(orederType == 1){
        if(pay){
            console.log('500優惠券');
        }else {
            if(stock > 0){
                console.log('普通購物頁面');
            }else {
                console.log('已無貨');
            }
        }
    }else if(orederType == 2){
        if(pay){
            console.log('200優惠券');
        }else {
            if(stock > 0){
                console.log('普通購物頁面');
            }else {
                console.log('已無貨');
            }
        }
    }else if(orederType == 3){
        if(stock > 0){
            console.log('普通購物頁面');
        }else {
            console.log('已無貨');
        }
    }
}

buyOrder(1, true, 600)

改進版本

var order500 = function(orderType, pay , stock){
    if(orderType == '1' && pay == true){
        console.log('500優惠券');
    }else {
        order200(orderType, pay , stock)
    }
}

var order200 = function(orderType, pay , stock){
    if(orderType == '2' && pay == true){
        console.log('200優惠券');
    }else {
        orderNormal(orderType, pay , stock)
    }
}

var orderNormal = function(orderType, pay , stock){
    if(stock > 0){
        console.log('普通購物頁面');
    }else {
        console.log('已無貨');
    }
}

order500(3, true, 0)

優化版本1:
同步的職責鏈

//3個訂單函數 ,它們都是節點函數
var order500 = function(orderType, pay , stock){
    if(orderType == '1' && pay == true){
        console.log('500優惠券');
    }else {
        return 'nextSuccessor';     //我不知道下個節點是誰,反正把請求往后傳遞
    }
}

var order200 = function(orderType, pay , stock){
    if(orderType == '2' && pay == true){
        console.log('200優惠券');
    }else {
        return 'nextSuccessor';     //我不知道下個節點是誰,反正把請求往后傳遞
    }
}

var orderNormal = function(orderType, pay , stock){
    if(stock > 0){
        console.log('普通購物頁面');
    }else {
        console.log('已無貨');
    }
}

//職責構造函數
var Chain = function(fn){
    this.fn = fn;
    this.successor = null;
}

Chain.prototype.setNextSuccessor = function(successor){     //設置職責順序方法
    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)     //500優惠券
chainOrder500.passRequest(3, true, 20)      //普通購物頁面
chainOrder500.passRequest(3, true, 0)       //已無貨

//此時如果中間有需求改動,只需如此做: 
var order300 = function(){
    if(orderType == '3' && pay == true){
        console.log('300優惠券');
    }else {
        return 'nextSuccessor';     //我不知道下個節點是誰,反正把請求往后傳遞
    }
}
var chainOrder300 = new Chain(order300)     //添加新職責節點
chainOrder500.setNextSuccessor(chainOrder300)
chainOrder300.setNextSuccessor(chainOrder300)   //修改職責鏈順序
chainOrder200.setNextSuccessor(chainOrderNormal)

//這樣,就可以完全不必去理會原來的訂單函數代碼,只需增加一個節點,然后重新設置職責鏈中的相關節點的順序就行。

優化版本2:異步的職責鏈

在實際開發中,經常會遇到 一些異步的問題,比如要在節點函數中發起一個ajax請求,異步請求返回的結果才能決定是否繼續在職責鏈中passRequest

可以給Chain類再增加一個原型方法:

//職責構造函數
var Chain = function(fn){
    this.fn = fn;
    this.successor = null;
}

Chain.prototype.setNextSuccessor = function(successor){     //設置職責順序方法
    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)
}


//異步職責鏈例子
var fn1 = new Chain(function(){
    console.log(1);
    return 'nextSuccessor'
})

var fn2 = new Chain(function(){
    console.log(2);
    var self = this;
    setTimeout(function(){
        self.next()
    }, 1000)
})

var fn3 = new Chain(function(){
    console.log(3);
})


//指定節點在職責鏈中的順序
fn1.setNextSuccessor(fn2)
fn2.setNextSuccessor(fn3)

//把請求傳遞給第一個節點,開始節點傳遞
fn1.passRequest()

//輸出 1 2 ...(1秒后)... 3

//這是一個異步職責鏈,請求在職責鏈節點中傳遞,但節點有權利決定什么時候 把請求交給下一個節點。這樣可以創建一個異步ajax隊列庫。

tips:

這里補充個知識點:“短路求值” && 會返回第一個假值(0, null, "", undefined, NaN),而 || 則會返回第一個真值。

var x = a || b || c 等價于:

var x;
if(a){
    x = a;
} else if(b){
    x = b;
} else {
    x = c;
}

var x = a && b && c 等價于:

var x = a;
if(a){
    x = b;
    if(b){
        x = c;
    }
}

所以 && 有時候會用來代替 if (expression) doSomething(),轉成 &&方式就是 expression && doSomething()

而 || 比較用來在函數中設置默認值,比如:

function doSomething(arg1, arg2, arg3) {
    arg1 = arg1 || 'arg1Value';
    arg2 = arg2 || 'arg2Value';
}

不過還需要看具體的使用場景,就比如如果要求 doSomething() 傳入的 arg1 為一個數值,則上面的寫法就會出現問題(在傳入 0 的時候被認為是一個假值而使用默認值)。

現在個人比較常用的方法只判斷是否與 undefined 相等,比如

function doSomething(arg) {
    arg = arg !== void 0 ? arg : 0;
}

職責鏈模式的優勢:解耦請求發送者和 N 個接收者之間的復雜關系,由于不知道鏈條中的哪個節點可以處理你發出的請求,所以只需把請求傳遞給第一個節點就行。

如果在實際開發中,當維護一個含有多個條件分支語句的巨大函數時時,可以使用職責鏈模式。鏈中的節點對象可以靈活拆分重組,增加刪除節點,且無需改動其他節點函數內的代碼。

以上就是關于“javascript職責鏈模式的代碼怎么寫”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

巨鹿县| 宿州市| 额济纳旗| 临清市| 西昌市| 禄劝| 沧州市| 闵行区| 忻城县| 台山市| 黄浦区| 伊通| 蕲春县| 三都| 舒兰市| 威远县| 怀安县| 文登市| 拉孜县| 新绛县| 宁都县| 驻马店市| 泾阳县| 栾川县| 拉萨市| 确山县| 于田县| 和硕县| 靖州| 洱源县| 大竹县| 河池市| 江孜县| 禹州市| 舒兰市| 海林市| 满城县| 和平县| 齐河县| 城市| 富民县|