1. <!DOCTYPE html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8" />
    5. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    6. <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    7. <title>发布订阅模式</title>
    8. </head>
    9. <body>
    10. <div class="eg2"></div>
    11. <script>
    12. // 创建一个第三方观察着构造函数
    13. class Observer {
    14. constructor() {
    15. // { type_1: [ cb1, cb2 ], type_1: [ cb1, cb2, cb3 ] }
    16. this.message = {};
    17. }
    18. // 1. 向消息队列里面添加内容
    19. on(type, cb = () => {}) {
    20. // 判断队列是否存在对应 type
    21. if (!this.message[type]) {
    22. // 表示消息队列里面还有注册过
    23. this.message[type] = [];
    24. }
    25. // 直接进行 push
    26. this.message[type].push(cb);
    27. }
    28. // 2. 删除消息队列里面的内容
    29. off(type, cb) {
    30. // 如果 cb 不存在, 删除整个对应type
    31. if (!cb) {
    32. delete this.message[type];
    33. return;
    34. }
    35. // 判断订阅类型是否存在
    36. if (!this.message[type]) return;
    37. // 删除 type 中的消息队列
    38. this.message[type] = this.message[type].filter((item) => item !== cb);
    39. }
    40. // 3. 触发消息队列
    41. trigger(type) {
    42. // 判断订阅类型是否存在
    43. if (!this.message[type]) return;
    44. this.message[type].forEach((cb) => {
    45. cb();
    46. });
    47. }
    48. }
    49. const person = new Observer();
    50. person.on("a", handlerA);
    51. person.on("a", handlerB);
    52. person.on("b", handlerB);
    53. person.on("b", handlerC);
    54. person.off("a");
    55. person.off("a", handlerA);
    56. person.trigger("a");
    57. console.log(person);
    58. function handlerA() {
    59. console.log("handlerA");
    60. }
    61. function handlerB() {
    62. console.log("handlerB");
    63. }
    64. function handlerC() {
    65. console.log("handlerC");
    66. }
    67. </script>
    68. </body>
    69. </html>