Tapable源码解读(一) --- 整体流程分析

前言


整个Tapable模块的实现基于两个基础类:Hook类(所有钩子类的基类)和HookCodeFactory(工厂类)。充分理解这两个类的实现原理,我们就算是真正读懂了Tapable。

在真正开始阅读源码之前,我们需要了解一下Tapable实现了哪些功能,能帮助我们解决问题。我们先来看以下这张图:

基本使用流程

上图是Tapable的基本使用方法,Tapable实现的也是一种订阅发布模式,创建Hook类实例的过程等同于创建了一个匿名事件的事件管理器。调用实例的tap/tapAsync/tapPromise则是为这个匿名事件绑定特定的消费者。而调用实例的call/callAsync/promise方法就是发布事件消息的过程。


如何处理回调函数


理论上讲,每个消费者都会定义一个回调函数用来响应事件。当存在多个消费者时,一个事件的发布就会触发多个回调函数,如何处理这些回调函数会比较复杂。Tapable定义了三种情况:

A1、同步回调函数的串行执行

A2、异步回调函数的串行执行

A3、异步回调函数的并行执行

与此同时,Tapable还定义4种特殊的处理逻辑,进一步提高了回调函数处理的灵活性和复杂性:

B1、Basic:基础类型,单纯的调用注册的事件回调,并不关心其内部的运行逻辑

B2、Bail:保险类型,当一个事件回调运行时返回的值不为undefined时,停止后面事件回调的执行

B3、Waterfail: 瀑布类型,如果当前执行的事件回调返回值不为undefined时,那么就把下一个事件回调的第一个参数替换成这个值

B4、Loop: 循环类型,如果当前执行的事件回调的返回值不是undefined,重新从第一个注册的事件回调处执行,直到当前执行的事件回调没有返回值

结合以上种种Tapable定义了Hook的10个子类(并行方式没法结合Waterfail和Loop类型使用):

// 同步串行

SyncHook --- A1 & B1

SyncBailHook --- A1 & B2

SyncWaterfallHook --- A1 & B3

SyncLoopHook --- A1 & B4

// 异步并行

AsyncParallelHook --- A3 & B1

AsyncParallelBailHook --- A3 & B2(这种类似于Promise.run这种赛跑机制)

// 异步串行

AsyncSeriesHook --- A2 & B1

AsyncSeriesBailHook --- A2 & B2

AsyncSeriesWaterfallHook --- A2 & B3

AsyncSeriesLoopHook --- A2 & B4


结语


根据需求我们可以选择相应的子类,Tapable提供的这10个子类提供的功能已足够完善,当然我们也可以自己扩展相应的子类。至此,我们已经从整体上了解了Tapable,后续文章我们将从源码角度解析Tapable的实现细节。