“这是我参与8月更文挑战的第21天,活动详情查看:8月更文挑战”
前言
在面试高级前端时,往往会遇到一些关于设计模式的问题,每次都回答不太理想。恰逢8月更文挑战的活动,准备用一个月时间好好理一下关于设计模式方面的知识点,给自己增加点面试的底气。
在 上一篇实现了一个可以灵活拆卸的职责链,但是其中职责链节点都是同步请求的,同步返回一个标识是否继续请求下一个职责链节点。本文将介绍职责链节点中式异步请求的,该如何处理。
异步的职责链节点
当一个职责链节点的请求是异步时,在其中同步返回一个继续请求下一个节点的标识已经不起作用了,得给它一个方法自己向下一个节点发起请求。
于是给创建职责链节点的类加一个方法next
,
class Chain{
constructor(fn){
this.fn = fn;
this.nextNode = null;
}
setNextNode(fn){
return this.nextNode = fn;
}
passRequest(){
const res = this.fn.apply(this,arguments);
if(res === 'toNextNode'){
return this.nextNode && this.nextNode.passRequest.apply(this.nextNode, arguments);
}
return res;
}
next(){
return this.nextNode && this.nextNode.passRequest.apply(this.nextNode, arguments);
}
}
然后这样使用:
const fn1 = new Chain(function () {
console.log(1);
return 'toNextNode';
});
const fn2 = new Chain(function () {
console.log(2);
var self = this;
setTimeout(function () {
self.next();
}, 1000);
});
const fn3 = new Chain(function () {
console.log(3);
});
fn1.setNextNode(fn2).setNextNode(fn3);
fn1.passRequest();
利用JavaScript的函数特性实现职责链模式
重写Function.prototype.after
实现职责链模式。
Function.prototype.after=function(fn){
const self = this;
return function(){
const res = self.apply(this,arguments);
if(res == 'toNextNode'){
return fn.apply(this,arguments);
}
return res
}
}
const order = order1000.after(order500).after(orderNormal);
order(1,true,500);// 1000元定金预定,得到500元优惠券
这种把函数叠在一起的方式来实现职责链模式,虽然更加方便的创建职责链,但是也叠加了函数的作用域,如果链条太长的话,会对性能有较大的影响。
职责链模式的优点
在之前文章中已经说过,职责链模式的最大优点就是解耦了请求发送者和 N 个接收者之间的复杂关 系,由于不知道链中的哪个节点可以处理你发出的请求,所以你只需把请求传递给第一个节点即 可。
其次,使用了职责链模式之后,链中的节点对象可以灵活地拆分重组。增加或者删除一个节 点,或者改变节点在链中的位置都是轻而易举的事情。
职责链模式还有一个优点,那就是可以手动指定起始节点,请求并不是非得从链中的第一个
节点开始传递。比如在公交车的例子中,如果我明确在我前面的第一个人不是售票员,那我当然
可以越过他把一块钱递给他前面的人,这样可以减少请求在链中的传递次数,更快地找到合适的
请求接受者。这在普通的条件分支语句下是做不到的,在其中没有办法让请求越过某一个if
判断。
另外,职责链模式使得程序中多了一些节点对象,可能在某一次的请求传递过程中,大部分 节点并没有起到实质性的作用,它们的作用仅仅是让请求传递下去,从性能方面考虑,我们要避 免过长的职责链带来的性能损耗。
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!