https://blog.csdn.net/sinat_41871344/article/details/82708684
https://www.cnblogs.com/null11/p/7498820.html
https://zhuanlan.zhihu.com/p/144832214
https://blog.csdn.net/csdnnews/article/details/107273877

UML类图

image.png

发布订阅代码实现

设计一个发布订阅模块

  1. class Subscribe {
  2. }

jquery发布订阅

$.Callbacks()

  • add
  • remove
  • fire
  • once

    1. (function() {
    2. class Subscribe {
    3. constructor() {
    4. // 创建一个事件池,用来存储后面需要执行的方法
    5. this.pond = []
    6. }
    7. // 向事件池中添加方法
    8. add (func) {
    9. if(typeof func !== 'function') return
    10. // 重复处理
    11. const include = this.pond.some(item => item === func)
    12. if(!include) this.pond.push(func)
    13. }
    14. // 把事件池中的方法,按照顺序依次执行
    15. emit(...args) {
    16. const { length } = this.pond
    17. for (let i = 0;i < length;i++) {
    18. const item = this.pond[i]
    19. if (typeof item !== 'function') {
    20. // 如果当前项不是函数,直接删除当前项,跳过当前循环
    21. this.pond.splice(i, 1)
    22. i--;
    23. continue;
    24. }
    25. // 三个以上的参数,call性能好于 apply
    26. item.call(this, ...args)
    27. }
    28. }
    29. once(func) {
    30. if(typeof func !== 'function') return
    31. func()
    32. this.remove(func)
    33. }
    34. // 从事件池中删除方法
    35. off(func) {
    36. this.pond
    37. }
    38. }
    39. // return 实例,暴露接口
    40. return () => new Subscribe()
    41. })()

    使用发布订阅模式 ```javascript const sub = new Subscribe()

// 创建事件池 const pond = subscribe()

document.querySelect(‘.submit’).onclick = function(ev) { pond.emit(ev) } ```

数组塌陷问题

删除一个后,原有数组的每一项都向前移动了一位,
但还是按照原来的顺序循环,导致中间的某几项直接跳过,
jquery3.x修复了跳过的bug
image.png