前言
接触hook是从webhook开始接触的,webhook是git的一个扩展服务,可以在仓库接收到push/commit事件并发送http request至一个开发者可以自定义的URL。
通过这个,我们可以在服务器实现若干自动化流程(诸如更新最新代码,打包编译,部署)
而webhook的技术原理,是来自于git的hook机制,简单来说,git的hook机制是 在一些常用的git 命令之后去触发一些开发者自定义的脚本(这些脚本存在于本地,在.git/hooks下)
如下图:

- git-hook 提供统一接口
- 开发者根据接口去写脚本
- webhook只是别人写好的脚本,当然自己也可以写(可以不是发送请求)
git-hook 伪代码
个人认为hook会按照如下伪代码去实现
received 'commit' event // 接受到commit事件
...一些commit的执行代码
if('pre-commit.sh' exist){
trigger 'pre-commit.sh' // 触发pre-commit脚本
}
emit 'commited' // 完成commit的标志
pre-commit这个状态是由git本身所定义的,它会在commit事件执行前去执行一个脚本(如果这个脚本存在),而这个脚本是开发者自己写的。当然你可以理解为
- 脚本最开始存在,只不过内容为空
- 开发者补充脚本内容实现自定义功能
从Vue源码看Hook
Vue的各生命周期,其实就是Vue开发者规定的一些hook,和git里面规定的hook类似,你只要往hook里面填自定义内容,它就可以执行。如vue实例里的beforeCreate,created,mounted等,都是hook。
简单来说,hook其实就是一种回调函数,只不过这种回调函数的名称已经被固定,内容不固定,且函数名称作为了一个接口被暴露出去。这样也更好了进行了抽。将经常变化的内容抽象暴露出去,将固定不变的代码进行封装。
假如Vue生命周期没有设计Hook,那么自定义的一些业务逻辑将深深与框架本身耦合,也就是说,你要在框架内部去写业务逻辑。
Vue生命周期中Hook源码浅析
在vue源码的/src/core/instance/lifecycle.js,有Vue声明周期的定义和hook的实现,callHook方法是触发hook之后的执行函数:

- 第一个参数
vm是传入的vue实例,handlers选取的vue实例里关于特定hook的所有方法。这里简单猜测一下vm.$options中的内容
vm.$options = {
'beforeCreate':[
function a (){},
function b (){},
... // a,b均是自己在实例里面定义的
],
'created':[],
'beforeMount':[],
'mounted':[]
....
}
遍历handlers将会遍历出在指定生命周期里开发者定义的不同方法,handler[i].call(vm)则是在vm的上下分环境下去执行handler[i]。
- 第二个参数则是上文提到的指定的
hook string,诸如beforeCreate,created,beforeMount,mounted...
接下来,我们再看下在哪里调用的callHook
同样在/src/core/instance/lifecycle.js里:





在不同的生命周期执行函数都执行了一次callHook,那么如果开发者在实例中的指定生命周期内定义了方法,这些方法就会在callHook里被执行(以实例的上下文)
总结
HOOK是一个非常好的设计,据说来源于Liunx操作系统设计,从Git到Vue,都能找到HOOK的影子,特别是对于JavaScript这门以事件驱动的单线程语言里,更为适用。
仔细想想JQuery里:
$.ajax({
method:'GET',
URL:'http://*****',
data:{},
success:()=>{},
fail:()=>{}
})
里面的sucess和fail方法会在xhr回调后执行,这也是一种hook,为了方便理解,你可以将hook理解为callBackFunction(回调函数)。但是实际hook应用里面,回调函数函数名和函数实现细节已经被抽象暴露出来进行单独维护和修改。这一点极大增强了可扩展性。
本文深入探讨了Hook机制在软件开发中的应用,从Git的webhook到Vue的生命周期钩子,揭示了Hook作为回调函数的一种高级形式如何增强代码的可扩展性和解耦特性。
243

被折叠的 条评论
为什么被折叠?



