Js编程技巧之jQuery源码(Callbacks模块设计流程与思想)

240 阅读2分钟

本文是专栏《Js编程技巧之jQuery源码分析》的第三篇,介绍一下Callback模块。它本质上是一种观察者(订阅者)设计模式。这种模式在jQuery里具体实现是怎样的?有哪些核心的概念,本文会做探讨,不会面面俱到,但求清晰易于理解,抛砖引玉。

如何使用

通过.add添加观察者,然后通过.fire通知观察者

const cb = $.Callbacks()
cb.add(function(msg){
  console.log("first add: " + msg)
})
cb.add(function(msg){
  console.log("second add: " + msg)
})
cb.fire("hello")
//output
//"first add: hello"
//"second add: hello"

重要概念简介

初始化

  • $.Callbacks:该工厂函数执行初始化并返回一个组装好的cb对象
  • list:一个列表,存储着添加过的观察者(函数)
  • queue:一个队列存储着待执行的消息体
  • locked:记录cbObj对象的锁定状态
  • fire:内部函数,负责将queue里的消息体通知到所有观察者(函数)
  • cbObj:返回的对象,暴露了一系列的方法

暴露方法

  • add:添加观察者函数到list数组
  • remove:移除某个观察者函数
  • empty:清空list数组
  • fire:调用fireWith
  • fireWith:将接收的消息通知到观察者体;
  • lock:锁定cbObj
  • disable:禁用cbObj

流程图

在这里插入图片描述

可借鉴的设计技巧

$.Callbacks函数巧妙参数设计

$.Callback接受字符串和Js对象两种参数形式,字符串如"once memory"会被解析为{ once:true,memory:true }的对象,缺省的参数会被当作false

这样简化了入参流程,对于那些仅需设置true、false的参数非常有效。

分拆fire过程

在源码里,没有简单地把fire实现写到一个函数里,而是抽象了三个方法,流程更加清晰:

  1. 暴露的fire方法。不需要设置函数执行上下文(默认以cbObj为上下文)
  2. 暴露的fireWith方法。可以设置观察者函数执行上下文
  3. 实际负责执行、清空queue的内部函数fire

1和2负责设置观察者函数地执行上下文、添加消息体到队列里;3负责具体执行队列里的消息通知。