前端小知识点扫盲笔记记录7-2

简介: 前端小知识点扫盲笔记记录7

发布-订阅者模式例子

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>发布--订阅者模式</title>
</head>
<body>
  <script>
    ////定义一所学校(中间件,事件派发中心)
    //主要功能包括校园网(topics),以及学生订阅消息(subscribe),老师发布课程(publish)
    let School = {
      type: "hunt",
      topics: Object.create(null),
      //添加订阅的事件,当一个对象订阅事件的时候,分别传入事件名字和回调函数(当订阅事件触发时候执行的操作)
      subscribe: function (topic, fn) {
        //如果派发对象内检索不到这个对象,就说明是一个新事件,新建一个数组对象,然后把该订阅者的回调放进事件对象中
        //topics是一个对象,里面有多个事件对象,事件对象内部是一个数组,包含这个事件的订阅者
        if (!this.topics[topic]) {
          this.topics[topic] = [];
          console.log("添加订阅" + topic + "的学生到Peter老师的订阅对象中");
          this.topics[topic].push(fn);
        }
      },
      // 发布事件,在事件订阅对象中检索这个事件,有就调用该对象中所有回调,否则直接返回
      publish: function (topic, money) {
        if (!this.topics[topic]) return;
        for (let fn of this.topics[topic]) {
          console.log("校园网发布" + topic + "课程");
          fn(money);
        }
      }
    }
    //定义一个师生类
    //包括姓名,身份
    function Student(name, identity) {
      this.name = name;
      this.identity = identity;
      //师生可以在校园网上发布订阅任务  //定义一个订阅函数,这里面调用了任务中心的订阅函数,收集所有订阅者的订阅事件和回调
      this.subscribe = function subscribe(topic, fn) {
        console.log(this.identity + "的" + this.name + "在校园网订阅了" + topic + "的课程");
        School.subscribe(topic, fn);
      };
      //定义一个发布函数,这里面调用了任务中心的发布函数,调用所有订阅者的回调  
      this.publish = function publish(topic, money) {
        console.log(this.identity + "老师" + this.name + "在校园网发布了" + topic + "的课程");
        School.publish(topic, money);
      };
    }
    //案例开始,先定义学生,老师
    let studentMing = new Student("小明", "大一");
    let studentJin = new Student("小金", "大一");
    let studentZhang = new Student("小张", "大一");
    let studentPeter = new Student("Peter", "老师");
    //小明,小金,小张分别订阅了发布课程
    studentMing.subscribe("Peter老师", function (money) {
      console.log("小明表示:" + (money = "美术课" ? "不" : "") + "接取美术课");
    });
    studentJin.subscribe("Peter老师", function (money) {
      console.log("小金表示:接取任何课程");
    });
    studentZhang.subscribe("Peter老师", function (money) {
      console.log("小张表示:" + (money = "前端课" ? "我不上其他课," : "") + "我要上前端课啊");
    });
    //Peter发布了课程,美术课
    studentPeter.publish("Peter老师", "美术课");
  </script>
</body>
</html>

发布订阅者模式

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>发布订阅者模式</title>
</head>
<body>
  <script>
    // 创建一个对象
    // 在该对象上创建一个缓存列表( 调度中心)
    // on 方法用来把函数 fn 都加到缓存列表中( 订阅者注册事件到调度中心)
    // emit 方法取到 arguments 里第一个当做 event, 根据 event 值去执行对应缓存列表中的函数( 发布者发布事件到调度中心, 调度中心处理代码)
    // off 方法可以根据 event 值取消订阅( 取消订阅)
    // once 方法只监听一次, 调用完毕后删除缓存函数( 订阅一次)
    // 公众号对象
    // let eventEmitter = {};
    // // 缓存列表,存放 event 及 fn
    // eventEmitter.list = {};
    // // 订阅
    // eventEmitter.on = function (event, fn) {
    //   console.log(this,"this")
    //   let _this = this;
    //   // 如果对象中没有对应的 event 值,也就是说明没有订阅过,就给 event 创建个缓存列表
    //   // 如有对象中有相应的 event 值,把 fn 添加到对应 event 的缓存列表里
    //   (_this.list[event] || (_this.list[event] = [])).push(fn);
    //   return _this;
    // };
    // // 发布
    // eventEmitter.emit = function () {
    //   console.log(this,"this")
    //   let _this = this;
    //   // 第一个参数是对应的 event 值,直接用数组的 shift 方法取出
    //   console.log(arguments,"arguments")
    //   let event = [].shift.call(arguments),
    //     fns = [..._this.list[event]];
    //   // 如果缓存列表里没有 fn 就返回 false
    //   if (!fns || fns.length === 0) {
    //     return false;
    //   }
    //   // 遍历 event 值对应的缓存列表,依次执行 fn
    //   fns.forEach(fn => {
    //     fn.apply(_this, arguments);
    //   });
    //   return _this;
    // };
    // function user1(content) {
    //   console.log('用户1订阅了:', content);
    // };
    // function user2(content) {
    //   console.log('用户2订阅了:', content);
    // };
    // // 订阅
    // eventEmitter.on('article', user1);
    // eventEmitter.on('article', user2);
    // // 发布
    // eventEmitter.emit('article', 'Javascript 发布-订阅模式');
    // /*
    //     用户1订阅了: Javascript 发布-订阅模式
    //     用户2订阅了: Javascript 发布-订阅模式
    // */
    let eventEmitter = {
      // 缓存列表
      list: {},
      // 订阅
      on(event, fn) {
        let _this = this;
        // 如果对象中没有对应的 event 值,也就是说明没有订阅过,就给 event 创建个缓存列表
        // 如有对象中有相应的 event 值,把 fn 添加到对应 event 的缓存列表里
        (_this.list[event] || (_this.list[event] = [])).push(fn);
        return _this;
      },
      // 监听一次
      once(event, fn) {
        // 先绑定,调用后删除
        let _this = this;
        function on() {
          _this.off(event, on);
          fn.apply(_this, arguments);
        }
        on.fn = fn;
        _this.on(event, on);
        return _this;
      },
      // 取消订阅
      off(event, fn) {
        let _this = this;
        let fns = _this.list[event];
        // 如果缓存列表中没有相应的 fn,返回false
        if (!fns) return false;
        if (!fn) {
          // 如果没有传 fn 的话,就会将 event 值对应缓存列表中的 fn 都清空
          fns && (fns.length = 0);
        } else {
          // 若有 fn,遍历缓存列表,看看传入的 fn 与哪个函数相同,如果相同就直接从缓存列表中删掉即可
          let cb;
          for (let i = 0, cbLen = fns.length; i < cbLen; i++) {
            cb = fns[i];
            if (cb === fn || cb.fn === fn) {
              fns.splice(i, 1);
              break
            }
          }
        }
        return _this;
      },
      // 发布
      emit() {
        let _this = this;
        // 第一个参数是对应的 event 值,直接用数组的 shift 方法取出
        let event = [].shift.call(arguments),
          fns = [..._this.list[event]];
        // 如果缓存列表里没有 fn 就返回 false
        if (!fns || fns.length === 0) {
          return false;
        }
        // 遍历 event 值对应的缓存列表,依次执行 fn
        fns.forEach(fn => {
          fn.apply(_this, arguments);
        });
        return _this;
      }
    };
    function user1(content) {
      console.log('用户1订阅了:', content);
    }
    function user2(content) {
      console.log('用户2订阅了:', content);
    }
    function user3(content) {
      console.log('用户3订阅了:', content);
    }
    function user4(content) {
      console.log('用户4订阅了:', content);
    }
    // 订阅
    eventEmitter.on('article1', user1);
    eventEmitter.on('article1', user2);
    eventEmitter.on('article1', user3);
    // 取消user2方法的订阅
    eventEmitter.off('article1', user2);
    eventEmitter.once('article2', user4)
    // 发布
    eventEmitter.emit('article1', 'Javascript 发布-订阅模式');
    eventEmitter.emit('article1', 'Javascript 发布-订阅模式');
    eventEmitter.emit('article2', 'Javascript 观察者模式');
    eventEmitter.emit('article2', 'Javascript 观察者模式');
    // eventEmitter.on('article1', user3).emit('article1', 'test111');
    /*
        用户1订阅了: Javascript 发布-订阅模式
        用户3订阅了: Javascript 发布-订阅模式
        用户1订阅了: Javascript 发布-订阅模式
        用户3订阅了: Javascript 发布-订阅模式
        用户4订阅了: Javascript 观察者模式
    */
  </script>
</body>
</html>
相关文章
|
存储 人工智能 前端开发
前端大模型应用笔记(三):Vue3+Antdv+transformers+本地模型实现浏览器端侧增强搜索
本文介绍了一个纯前端实现的增强列表搜索应用,通过使用Transformer模型,实现了更智能的搜索功能,如使用“番茄”可以搜索到“西红柿”。项目基于Vue3和Ant Design Vue,使用了Xenova的bge-base-zh-v1.5模型。文章详细介绍了从环境搭建、数据准备到具体实现的全过程,并展示了实际效果和待改进点。
1122 14
|
JavaScript 前端开发 程序员
前端学习笔记——node.js
前端学习笔记——node.js
387 0
|
Web App开发 前端开发 Linux
「offer来了」浅谈前端面试中开发环境常考知识点
该文章归纳了前端开发环境中常见的面试知识点,特别是围绕Git的使用进行了详细介绍,包括Git的基本概念、常用命令以及在团队协作中的最佳实践,同时还涉及了Chrome调试工具和Linux命令行的基础操作。
「offer来了」浅谈前端面试中开发环境常考知识点
|
SpringCloudAlibaba JavaScript 前端开发
谷粒商城笔记+踩坑(2)——分布式组件、前端基础,nacos+feign+gateway+ES6+vue脚手架
分布式组件、nacos注册配置中心、openfegin远程调用、网关gateway、ES6脚本语言规范、vue、elementUI
谷粒商城笔记+踩坑(2)——分布式组件、前端基础,nacos+feign+gateway+ES6+vue脚手架
|
人工智能 自然语言处理 运维
前端大模型应用笔记(一):两个指令反过来说大模型就理解不了啦?或许该让第三者插足啦 -通过引入中间LLM预处理用户输入以提高多任务处理能力
本文探讨了在多任务处理场景下,自然语言指令解析的困境及解决方案。通过增加一个LLM解析层,将复杂的指令拆解为多个明确的步骤,明确操作类型与对象识别,处理任务依赖关系,并将自然语言转化为具体的工具命令,从而提高指令解析的准确性和执行效率。
536 6
|
存储 弹性计算 算法
前端大模型应用笔记(四):如何在资源受限例如1核和1G内存的端侧或ECS上运行一个合适的向量存储库及如何优化
本文探讨了在资源受限的嵌入式设备(如1核处理器和1GB内存)上实现高效向量存储和检索的方法,旨在支持端侧大模型应用。文章分析了Annoy、HNSWLib、NMSLib、FLANN、VP-Trees和Lshbox等向量存储库的特点与适用场景,推荐Annoy作为多数情况下的首选方案,并提出了数据预处理、索引优化、查询优化等策略以提升性能。通过这些方法,即使在资源受限的环境中也能实现高效的向量检索。
704 1
|
机器学习/深度学习 弹性计算 自然语言处理
前端大模型应用笔记(二):最新llama3.2小参数版本1B的古董机测试 - 支持128K上下文,表现优异,和移动端更配
llama3.1支持128K上下文,6万字+输入,适用于多种场景。模型能力超出预期,但处理中文时需加中英翻译。测试显示,其英文支持较好,中文则需改进。llama3.2 1B参数量小,适合移动端和资源受限环境,可在阿里云2vCPU和4G ECS上运行。
687 1
|
前端开发 算法 测试技术
前端大模型应用笔记(五):大模型基础能力大比拼-计数篇-通义千文 vs 文心一言 vs 智谱 vs 讯飞vsGPT
本文对比测试了通义千文、文心一言、智谱和讯飞等多个国产大模型在处理基础计数问题上的表现,特别是通过链式推理(COT)提示的效果。结果显示,GPTo1-mini、文心一言3.5和讯飞4.0Ultra在首轮测试中表现优秀,而其他模型在COT提示后也能显著提升正确率,唯有讯飞4.0-Lite表现不佳。测试强调了COT在提升模型逻辑推理能力中的重要性,并指出免费版本中智谱GLM较为可靠。
680 0
前端大模型应用笔记(五):大模型基础能力大比拼-计数篇-通义千文 vs 文心一言 vs 智谱 vs 讯飞vsGPT
|
前端开发 JavaScript 数据库
如何实现前后端分离-----前端笔记
如何实现前后端分离-----前端笔记
|
存储 前端开发 JavaScript
前端语言串讲 | 青训营笔记
前端语言串讲 | 青训营笔记
402 0

热门文章

最新文章

  • 1
    前端如何存储数据:Cookie、LocalStorage 与 SessionStorage 全面解析
    617
  • 2
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(九):强势分析Animation动画各类参数;从播放时间、播放方式、播放次数、播放方向、播放状态等多个方面,完全了解CSS3 Animation
    262
  • 3
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(八):学习transition过渡属性;本文学习property模拟、duration过渡时间指定、delay时间延迟 等多个参数
    242
  • 4
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(七):学习ransform属性;本文学习 rotate旋转、scale缩放、skew扭曲、tanslate移动、matrix矩阵 多个参数
    189
  • 5
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(六):全方面分析css的Flex布局,从纵、横两个坐标开始进行居中、两端等元素分布模式;刨析元素间隔、排序模式等
    298
  • 6
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(五):背景属性;float浮动和position定位;详细分析相对、绝对、固定三种定位方式;使用浮动并清除浮动副作用
    427
  • 7
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(四):元素盒子模型;详细分析边框属性、盒子外边距
    186
  • 8
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(三):元素继承关系、层叠样式规则、字体属性、文本属性;针对字体和文本作样式修改
    128
  • 9
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(二):CSS伪类:UI伪类、结构化伪类;通过伪类获得子元素的第n个元素;创建一个伪元素展示在页面中;获得最后一个元素;处理聚焦元素的样式
    198
  • 10
    【CSS】前端三大件之一,如何学好?从基本用法开始吧!(一):CSS发展史;CSS样式表的引入;CSS选择器使用,附带案例介绍
    274