职责链模式的其他串联方式?
在学习javascript设计模式与实践一书中的职责链模式
var order500 = async function( orderType, pay, stock ){
if ( orderType === 1 && pay === true ){
let data = await fetch('http://10.11.4.66:3000/hello',{
headers: {
'Content-Type': 'application/json;charset=UTF-8',
},
})
// .then(res=>{
// res.json().then(data=>{
// console.log(data)
// return data
// })
// })
if(data){
let res = await data.json()
if(res.data){
return 'nextSuccessor'
}
}
}else{
return 'nextSuccessor'; // 我不知道下一个节点是谁,反正把请求往后面传递
}
};
var order200 = function( orderType, pay, stock ){
if ( orderType === 2 && pay === true ){
console.log( '200 元定金预购,得到 50 优惠券' );
}else{
return 'nextSuccessor'; // 我不知道下一个节点是谁,反正把请求往后面传递
}
};
var orderNormal = function( orderType, pay, stock ){
if ( stock > 0 ){
console.log( '普通购买,无优惠券' );
}else{
console.log( '手机库存不足' );
}
};
function Aop(){
}
// 连接职责节点
Function.prototype.after = function( fn ){
var self = this; // js中一切都是对象 function也是对象 所以this可以指向fun
return async function(){
var ret = await self.apply( this, arguments );
if ( ret === 'nextSuccessor' ){
return fn.apply( this, arguments );
}
// return ret;
}
};
var order = order500.after( order200 ).after( orderNormal );
order( 1, true, 500 ); // 输出:500 元定金预购,得到 100 优惠券
order( 2, true, 500 ); // 输出:200 元定金预购,得到 50 优惠券
order( 1, false, 500 ); // 输出:普通购买,无优惠券
为了更贴近业务增加了异步请求,又觉得Function.prototype.after 直接在Function的原型链上做了修改可能不太好, 然后有了两个想法 1.在每个职责方法的prototype上添加after方法 但是觉得很麻烦 2.让每个职责方法继承同一个方法的原型 但是并不能像new 出来的object那样操作原型链(或者说我并不知道该怎么操作) 书中还有个通过类实现的方法 也比较繁琐
想问一下大佬们有什么好的实现方法或者思路吗
后续实现
将问题转化成了多个异步按顺序执行 并且根据结果判断是否继续执行
// 带有异步的职责链模式
var order500 = async function (orderType, pay, stock) {
if (orderType === 1 && pay === true) {
let data = await fetch('http://10.11.4.66:3000/hello', {
headers: {
'Content-Type': 'application/json;charset=UTF-8',
},
})
// .then(res=>{
// res.json().then(data=>{
// console.log(data)
// return data
// })
// })
if (data) {
let res = await data.json()
if (res.data) {
console.log("500")
return '1'
}
}
} else {
return 'nextSuccessor'; // 我不知道下一个节点是谁,反正把请求往后面传递
}
};
var order200 = async function (orderType, pay, stock) {
if (orderType === 2 && pay === true) {
console.log('200 元定金预购,得到 50 优惠券');
} else {
return 'nextSuccessor'; // 我不知道下一个节点是谁,反正把请求往后面传递
}
};
var orderNormal = async function (orderType, pay, stock) {
if (stock > 0) {
console.log('普通购买,无优惠券');
} else {
console.log('手机库存不足');
}
};
function Chain(...fn) {
console.log(fn)
this.fn = fn
}
Chain.prototype.do = function (...args) {
let start = 0
if (start > this.fn.length || start < 0) return; // 参数start不能超过 arr.length,不能为负数
let next = (i) => {
if (i < this.fn.length) {
let fn = this.fn[i]; // 所以每个职责节点必须返回promis 也可以判断类型是不是promise做一下兼容没有返回promise的情况?
fn(...args).then(res => {
// console.log(res);
if (res == 'nextSuccessor') {
i++;
next(i)
}
})
}
}
next(start)
return this
}
new Chain(order500, order200, orderNormal).do(1, true, 500).do(2, true, 500).do(1, false, 500 )
每个chain对象都是一条职责链 根据传入的方法顺序进行执行
5 回复
function Chain(arg) {
this.value = arg
}
Chain.prototype.add = function (func) {
this.value = func(this.value)
return this
}
Chain.prototype.valueOf = function() {
return this.value
}
new Chain(data).
add(dataMsg).
add(dataFormat).
add(listFormat).
valueOf()
@teenth 谢谢 受你的启发又写了一个出来 包含异步的话函数执行的顺序是会变的
@zhsonga 异步可以使用 promise 使用resolve
@teenth add中有异步的话Chain(data).add(dataMsg).add(dataFormat).add(listFormat).valueOf()这种链式的调用方式会出问题
@zhsonga 这个肯定得改