返回

职责链模式

var Chain = function(fn) {
  this.fn = fn;
  this.successor = null;
}
Chain.prototype.run = function() {
  var result = this.fn && this.fn(..._args);
  if(result === true) {
    return this.successor && this.successor.run.apply(this.successor,arguments)
  }
  return result;
}
Chain.prototype.next = function(fn) {
  return this.successor = fn instanceof Chain?fn:new Chain(fn);

}

var fn1 = function() {
  console.log(1);
  return true;
}
var fn2 = function() {
  console.log(2);
  return true;
}
var fn3 = function() {
  console.log(3);
  return true;
}
let c = new Chain(fn1);
let m = c.next(fn2).next(fn3)+
c.run();
var Chain = function() {
  let _args = arguments;
  return {
    fnArr: [],
    currentIndex: 0,
    addNext: function(fn) {
      return this.fnArr.push(fn), this;
    },
    run: function() {
      let i = this.currentIndex;
      let fnArr = this.fnArr;
      let length = fnArr.length;
      for (; i < length; ++i) {
        this.currentIndex = i;
        let fn = fnArr[i];
        let result = fn(..._args);
        if (result !== true) {
          break;
        }
      }
      if(i === length) {
        this.init();
      }
    },
    init: function() {
      this.currentIndex = 0;
      this.fnArr = [];
    },
    next:function() {
      this.currentIndex ++;
      this.run();
    }
  };
};
let ca = Chain("m");
var fn1 = function(prefix) {
  console.log(prefix+'1');
  return true;
};
var fn2 = function(prefix) {
  console.log(prefix+'2');
  setTimeout(()=>{
    ca.next();
  },1000)
};
var fn3 = function(prefix) {
  console.log(prefix+'3');
  return false;
};
ca.addNext(fn1).addNext(fn2).addNext(fn3).run();
// 对象池改善职责链模式
var Chain = function() {
  let _args = arguments;
  let _ObjectPool = [];
  return _ObjectPool.length?_ObjectPool.pop():{
    expectResult: true, // 让它进入到下一环节的收到的预期结果
    fnArr: [], // 所有环节
    currentIndex: 0, // 进行到的环节
    addNext: function(fn) {
      return this.fnArr.push(fn), this;
    } ,// 添加下一环节
    run: function() { // 运行环节
      let i = this.currentIndex;
      let fnArr = this.fnArr;
      let length = fnArr.length;
      for (; i < length; ++i) {
        this.currentIndex = i;
        let fn = fnArr[i];
        let result = fn(..._args);
        if (result !== this.expectResult) {
          break;
        }
      }
      if(i === length) {
        this.init();
      }
    },
    init: function() { // 恢复初始化
      this.expectResult = true;
      this.currentIndex = 0;
      this.fnArr = [];
      this.recover();
    },
    next:function() {
      this.currentIndex ++;
      this.run();
    }, // 接着往下执行
    recover: function() {
      _ObjectPool.push(this)
    } // 回收对象
  };
};
let ca = Chain("m");
var fn1 = function(prefix) {
  console.log(prefix+'1');
  return true;
};
var fn2 = function(prefix) {
  console.log(prefix+'2');
  setTimeout(()=>{
    ca.next();
  },1000)
};
var fn3 = function(prefix) {
  console.log(prefix+'3');
  return false;
};
ca.addNext(fn1).addNext(fn2).addNext(fn3).run();
// 添加回收变量
var Chain = function(obj) {
  let _args = arguments;
  let _ObjectPool = [];
  return _ObjectPool.length?_ObjectPool.pop():{
    expectResult: true, // 让它进入到下一环节的收到的预期结果
    fnArr: [], // 所有环节
    currentIndex: 0, // 进行到的环节
    addNext: function(fn) {
      return this.fnArr.push(fn), this;
    } ,// 添加下一环节
    run: function() { // 运行环节
      let i = this.currentIndex;
      let fnArr = this.fnArr;
      let length = fnArr.length;
      for (; i < length; ++i) {
        this.currentIndex = i;
        let fn = fnArr[i];
        let result = fn(..._args);
        if (result !== this.expectResult) {
          break;
        }
      }
      if(i === length) {
        this.init(obj);
      }
    },
    init: function(obj) { // 恢复初始化
      this.expectResult = true;
      this.currentIndex = 0;
      this.fnArr = [];
      this.recover();
      obj = null;
    },
    next:function() {
      this.currentIndex ++;
      this.run();
    }, // 接着往下执行
    recover: function() {
      _ObjectPool.push(this)
    } // 回收对象
  };
};
let ca = Chain("m");
var fn1 = function(prefix) {
  console.log(prefix+'1');
  return true;
};
var fn2 = function(prefix) {
  console.log(prefix+'2');
  setTimeout(()=>{
    ca.next();
  },1000)
};
var fn3 = function(prefix) {
  console.log(prefix+'3');
  return false;
};
ca.addNext(fn1).addNext(fn2).addNext(fn3).run(ca)

var cb = Chain("k");
  cb.addNext(fn1).addNext(fn2).addNext(fn3);
  setTimeout(function() {
  cb.run();
},100)