javascript - 传递唯一参数的 Java Script Pub/Sub 模式
问题描述
使用 Java Script 中的发布/订阅者模式,例如,如果发布者发布了一个事件并且该事件有 3 个订阅者,如果一个订阅者需要一个“某个值”的参数来完成它的工作而另一个订阅者需要和“一些不同的价值”的论点来完成它的工作等?
所以 'func1'、'func2' 和 'func3' 将在按钮点击事件发布时触发。每个 'func' 都需要一个唯一的参数。此按钮单击代码只是示例。
let events = {},
subUid = -1;
let pubsub = {
subscribe : function(evt, func, args) {
if (!events[evt]) {
events[evt] = [];
};
let token = (++subUid).toString();
events[evt].push({
token : token,
func : func
});
return token;
},
unsubscribe : function(token) {
for (let m in events) {
if (events[m]) {
for (let i = 0, j = events[m].length; i < j; i++) {
if (events[m][i].token === token) {
events[m].splice( i, 1 );
return token;
};
};
};
};
return this;
},
publish : function(evt, args) {
if (!events[evt]) {
throw ''+evt+' doesn\'t exist!';
};
const subscribers = events[evt];
const len = (subscribers) ? subscribers.length : 0;
for (let i = 0; i < len; i++) {
subscribers[i].func(evt, args); // What to do here??!
};
return this;
}
};
/* - - - - - - - - - - 执行 - - - - - - - - - - */
$('#myButton').on('click', this, function(event) {
let someVal = [2, 3, 4];
someHandler(someVal);
});
const func1 = (evt, someVal)=> {
let total = someVal * 5;
console.log(total);
},
func2 = (evt, someDifferentVal)=> {
let total = someDifferentVal * 10;
console.log(total);
},
func3 = (evt, anotherDifferentVal)=> {
let total = anotherDifferentVal * 15;
console.log(total);
};
let subscription1 = pubsub.subscribe('newEventA', func1),
subscription2 = pubsub.subscribe('newEventA', func2),
subscription3 = pubsub.subscribe('newEventA', func3);
let someHandler = (args)=> {
pubsub.publish('newEventA', args);
};
解决方案
事件允许您将触发事件的组件与使用事件的组件分离。
让组件触发事件担心哪个消费者需要什么,这违背了事件的目的,假设是触发并忘记。
您的发布者应该将它可以提供的所有信息打包到参数中,并让消费者自己找出并提取相关信息。
例如,您可能希望发送额外的参数并将它们打包到一个对象中,而不是仅仅发送命令id
。publish
例如
pubsub.publish('newEventA', { id: 1, name: 'someName', ... });
需要 的事件id
将知道id
从参数中提取 ,而需要其他字段的事件将知道如何提取它们。
此外,您的平台可能有一个用于创建和触发自定义事件的库。
请参阅https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events
推荐阅读
- firebase - Cloud Firestore 数据是否跨大陆复制?
- amazon-web-services - 如果更新成功,有没有办法进行比较更新并触发 lambda 函数?
- swift - 如何在 Swift 中设计一个通用的观察者模式协议?
- reactjs - 为什么文本在反应中不匹配?
- javascript - 当元素快速调整大小时,JavaScript 的 offsetWidth 和 offsetHeight 给出错误的值
- python - 如何在python中对集合进行排序?
- webpack - 带有 Shopify Slate 主题的 jQuery
- jquery - $("select#mySelect option[value='option1']").remove() 当“select#mySelect”实际上是一个jQuery选择器?
- laravel-nova - 使用现有模板在 Nova 中导出 Excel
- json - 搜索端点中的 WP REST API (wp json) 不返回完整数据