SOURCE

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) {
    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)

//  orderType:表示订单类型(定金用户或者普通购买用户),code 的值为 1 的时候是 500 元 定金用户,为 2 的时候是 200 元定金用户,为 3 的时候是普通购买用户。
//  pay:表示用户是否已经支付定金,值为 true 或者 false, 虽然用户已经下过 500 元定金的 订单,但如果他一直没有支付定金,现在只能降级进入普通购买模式。
//  stock:表示当前用于普通购买的手机库存数量,已经支付过 500 元或者 200 元定金的用 户不受此限制。
// 最后把请求传递给第一个节点:
// chainOrder500.passRequest(1, true, 500); // 输出:500 元定金预购,得到 100 优惠券 
// chainOrder500.passRequest(2, true, 500); // 输出:200 元定金预购,得到 50 优惠券 
// chainOrder500.passRequest(3, true, 500); // 输出:普通购买,无优惠券
// chainOrder500.passRequest(1, false, 0); // 输出:手机库存不足



// // 异步链接
// 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();
//     }, 2000);
// });

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

// fn1.setNextSuccessor(fn2).setNextSuccessor(fn3);
// fn1.passRequest();



// AOE
Function.prototype.after = function (fn) {
    var self = this;
    return function () {
        var ret = self.apply(this, arguments)
        if (ret === 'nextSuccessor') {
            return fn.apply(this, arguments)
        }
        return ret
    }
}

var order = order500.after(order200).after(orderNormal);
order(1, true, 500); 
order(2, true, 500);
order(1, false, 500);
console 命令行工具 X clear

                    
>
console