本文是专栏《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
:调用fireWithfireWith
:将接收的消息通知到观察者体;lock
:锁定cbObjdisable
:禁用cbObj
流程图
可借鉴的设计技巧
$.Callbacks函数巧妙参数设计
$.Callback接受字符串和Js对象两种参数形式,字符串如"once memory"
会被解析为{ once:true,memory:true }
的对象,缺省的参数会被当作false
。
这样简化了入参流程,对于那些仅需设置true、false的参数非常有效。
分拆fire过程
在源码里,没有简单地把fire实现写到一个函数里,而是抽象了三个方法,流程更加清晰:
- 暴露的fire方法。不需要设置函数执行上下文(默认以
cbObj
为上下文) - 暴露的
fireWith
方法。可以设置观察者函数执行上下文 - 实际负责执行、清空queue的内部函数
fire
1和2负责设置观察者函数地执行上下文、添加消息体到队列里;3负责具体执行队列里的消息通知。