Appearance
chain 职责链
概述
该方法的好处是使多个对象都有机会处理请求,从而避免规则与使用之间的耦合,将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
通过new Chain(yourRules)传入规则创建节点,使用after通过AOP的方式将不同节点串联chain.after(yourRules2).after(yourRules3)
执行时使用chain.passRequest(yourArgs);,passRequest的参数会统一透传到每个节点规则中
其中rules在不满足当前条件,想要执行下个节点时需要return 'next',或者promise时resolve('next')
示例
假设我们负责一个售卖手机的电商网站,经过分别交纳 500元定金和 200元定金的两轮预定后(订单已在此时生成),现在已经到了正式购买的阶段。 公司针对支付过定金的用户有一定的优惠政策。在正式购买后, 已经支付过 500元定金的用户会收到 100元的商城优惠券, 200元定金的用户可以收到 50元的优惠券, 而之前没有支付定金的用户只能进入普通购买模式,也就是没有优惠券,且在库存有限的情况下不一定保证能买到。
ts
import { Chain } from '@ey-use/utils';
enum EOrderType {
prepay500,
prepay200,
normal,
}
function order500(orderType: EOrderType, pay: boolean, stock: number) {
if (orderType === EOrderType.prepay500 && pay) {
console.log('预付500元,得到100优惠');
} else {
return 'next';
}
}
function order200(orderType: EOrderType, pay: boolean, stock: number) {
if (orderType === EOrderType.prepay200 && pay) {
console.log('预付200元,得到100优惠');
} else {
return 'next';
}
}
function orderNormal(orderType: EOrderType, pay: boolean, stock: number) {
if (stock > 0) {
console.log('普通购买 无优惠券');
} else {
console.log('库存不足');
}
}
const chain = new Chain(order500);
// 将规则串联
chain.after(order200).after(orderNormal);
let stock = 3;
// 使用时直接输入规则,是否付款,库存让链子自己判断
chain.passRequest(EOrderType.prepay200, true, stock--);由上可看到,若接下来还有不同规则插入或去除时,我们只需修改chain.after即可,各个规则也能独立处理
示例2 异步处理
可采用this.next(需要确保this为Chain的回调所指向的执行环境)或promise.resove来异步运行职责链
ts
const fn1 = new Chain(function(){
console.log('1')
setTimeout(()=>{
this.next()
},3000)
})
fn1.after(function(){
return new Promise((resolve)=>{
console.log('2')
setTimeout(()=>{
resolve('next')
},2000)
})
}).after(()=>{
console.log('3')
})
fn1.passRequest()