职责链模式的其他串联方式? - CNode技术社区

职责链模式的其他串联方式?
发布于 6 年前 作者 zhsonga 5753 次浏览 来自 问答

在学习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 这个肯定得改

回到顶部

AltStyle によって変換されたページ (->オリジナル) /