>[success] # 异步职责链 ~~~ 1.上一个案例通过步返回一个特定的值"nextSuccessor",当有这个标记的时候认为他需要下一个职责节点, 但异步时候不一定什么时候执行完也导致不知道什么返回的到底是否是标记节点 2.解决方法通过自己手动去调用,当异步执行完毕后我们自己去调用下一个节点的方法,因此封装了一个next 方法,在异步执行完后自调用下一个节点 ~~~ >[danger] ##### 代码实现 ~~~ // 定义一个组合链子的类 var Chain = function (fn) { this.fn = fn this.successor = null } // 需要匹配的下一个节点 Chain.prototype.setNextSuccessor = function (successor) { return this.successor = successor } // 执行是否调用下一个节点 Chain.prototype.passRequest = function () { // 这里是异步 所以还没有数据执行会跳过到下一个,因此异步要用自己的next var ret = this.fn.apply( this, arguments ); if ( ret === 'nextSuccessor' ){ return this.successor && this.successor.passRequest.apply( this.successor, arguments ); } return ret; } // 异步执行完毕来自己判断是否走下一个节点, // 之前是通过是否返回标志符'nextSuccessor' 因为现在异步 // 就不能根据返回值来决定,只能是在异步时候来手动决定是否 // 调用下个节点 Chain.prototype.next= function(){ return this.successor && this.successor.passRequest.apply( this.successor, arguments ); }; ~~~ >[danger] ##### 使用 ~~~ 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 ).setNextSuccessor( fn3 ); fn1.passRequest(); ~~~