• JS提升:手写发布订阅者模式(小白篇)


    1. //以CSDN为例子
    2. function pubSub(){
    3. //存储CSDN关注了我的用户信息的数组
    4. this.accounts=[];
    5. }
    6. //subscribe 订阅
    7. pubSub.prototype.subscribe=function(key,callback){
    8. //key:我的账号
    9. if(!this.accounts[key]){
    10. //这里面存储的是哪些用户关注了我这个CSDN用户,有就取非直接跳出if
    11. this.accounts[key]=[]
    12. }
    13. //callback相当于用户,把这个用户放进这个关注我的数组中
    14. this.accounts[key].push(callback)
    15. }
    16. //publish 发布
    17. pubSub.prototype.publish=function(key,content){
    18. //通知所有关注了我这个账号的人
    19. this.accounts[key].forEach(user=>{
    20. user(content);
    21. })
    22. }
    23. //remove 移除关注我账号的人
    24. pubSub.prototype.remove=function(key,callback){
    25. // 判断是否有关注我,即消息队列里是否有type这个类型的事件,没有的话就直接return
    26. if (!this.accounts[key])
    27. return; //直接跳出循环
    28. // 判断是否有callback这个参数
    29. if (!callback) { // 如果没有callback,就是删掉整个事件
    30. this.accounts[key] = undefined;
    31. }else{
    32. // 如果有callback,就仅仅删除掉callback这个消息(过滤掉这个方法)
    33. this.accounts[key] = this.accounts[key].filter((item) => item !== callback);
    34. }
    35. }
    36. //中间代理,管理所有
    37. let pubsub=new pubSub();
    38. //订阅
    39. //大龙关注我,相当于给大龙绑定一个事件,等我发布文章就通知大龙
    40. let a=function follow1(content){
    41. console.log(content,'大龙收到来自我发布文章的消息');
    42. }
    43. pubsub.subscribe('我的账号',a)
    44. let b=function follow2(content){
    45. console.log(content,'小龙收到来自我发布文章的消息');
    46. }
    47. pubsub.subscribe('我的账号',b)
    48. let c=function follow3(content){
    49. console.log(content,'大大龙收到来自我发布文章的消息');
    50. }
    51. pubsub.subscribe('我的账号',c);
    52. //移除关注我的人
    53. pubsub.remove('我的账号',c);
    54. //发布
    55. //消息发布,只有关注了我账号的人才会即时推送我新发布文章的信息
    56. pubsub.publish('我的账号','中秋快乐');
    57. // key 就相当于是一个账号,callback 就相当于是关注这个账号的人
    58. // pubsub.publish(key,callback);

     

    1. class Observer {
    2. constructor() {
    3. this.message = {}; // 消息队列
    4. }
    5. // 向这个person1委托一些内容,调用person1 的'$on'方法
    6. // 向消息队列添加内容'$on'
    7. $on(type, callback) {
    8. // 判断有没有这个属性(时间类型)
    9. if (!this.message[type]) {
    10. // 如果没有这个属性,就初始化一个空的数组
    11. this.message[type] = [];
    12. }
    13. // 如果有这个属性,就往他的后面push一个新的callback
    14. this.message[type].push(callback);
    15. }
    16. // 删除消息队列里的内容
    17. $off(type, callback) {
    18. // 判断是否有订阅,即消息队列里是否有type这个类型的事件,没有的话就直接return
    19. if (!this.message[type])
    20. return;
    21. // 判断是否有callback这个参数
    22. if (!callback) { // 如果没有callback,就是删掉整个事件
    23. this.message[type] = undefined;
    24. }
    25. // 如果有callback,就仅仅删除掉callback这个消息(过滤掉这个方法)
    26. this.message[type] = this.message[type].filter((item) => item !== callback);
    27. }
    28. // 触发消息队列里的内容
    29. $emit(type) {
    30. //判断是否有订阅
    31. if(!this.message[type]) return;
    32. //如果有订阅,那就对‘type’事件做一个轮询(for循环)
    33. this.message[type].forEach(item=>{
    34. //挨个执行每一个消息的回调函数callback
    35. item();
    36. })
    37. }
    38. }
    39. function handlerA() {
    40. console.log('handlerA');
    41. }
    42. function handlerB() {
    43. console.log('handlerB');
    44. }
    45. function handlerC() {
    46. console.log('handlerC');
    47. }
    48. // 使用构造函数创建一个实例
    49. const person1 = new Observer();
    50. person1.$on('buy', handlerA);
    51. person1.$on('buy', handlerB);
    52. person1.$on('buy', handlerC);
    53. //删除handlerC信息
    54. person1.$off('buy',handlerC);
    55. console.log('person1 :>> ', person1);
    56. //触发buy事件
    57. person1.$emit('buy');

     

  • 相关阅读:
    【可靠性测试】什么是可靠性测试:定义、方法和工具
    在线考试系统
    zookper安装和群起脚本
    elment表格组件a-table属性formatter
    “大厂”角力移动办公系统市场,钉钉和企微向左、WorkPlus向右
    在nodejs常见的不良做法及其优化解决方案
    同样是玩手机,有人变有钱了,有人变贫穷了?
    辅助驾驶功能开发-功能规范篇(16)-2-领航辅助系统NAP-自动变道-1
    redis安装部署和常用命令
    vue(v-bind修改样式属性、自定义命令、过滤器filter)
  • 原文地址:https://blog.csdn.net/qq_51066068/article/details/126096427