这里有一份简洁的前端知识体系等待你查收,看看吧,会有惊喜哦~若是以为不错,恳求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。
职责链模式中多了一点节点对象,可能在某一次请求过程当中,大部分节点没有起到实质性做用,他们的做用只是让请求传递下去,从性能方面考虑,避免过长的职责链提升性能。