基本使用
同步钩子SyncHook
const { SyncHook } = require('./tapable/lib/index.js');class Lesson {constructor(props) {// 创建钩子this.hooks = {arch: new SyncHook(['name']),}}tap() { // 注册监听函数// 注册了两个事件, 叫lesson1和lesson2this.hooks.arch.tap('lesson1', function(name) {console.log('lesson1', name);})this.hooks.arch.tap('lesson2', function(name) {console.log('lesson2', name);})}start() {this.hooks.arch.call('jay');}}let l = new Lesson();l.tap(); // 把lesson1和lesson2的时间分别注册到一个数组中l.start(); // 启动钩子
打印结果为:
源码实现:
class SyncHook {constructor(args) {this.tasks = [];}tap(name, task) {this.tasks.push(task);}call(...args) {this.tasks.forEach(task => task(...args));}}
同步保险钩子SyncBailHook
当前一个注册函数返回值不为undefined时, 不继续向下执行
const { SyncBailHook } = require('./tapable/lib/index.js');class Lesson {constructor(props) {this.hooks = {arch: new SyncBailHook(['name']),}}tap() {this.hooks.arch.tap('lesson1', function(name) {console.log('lesson1', name);return 'stop learning'; // 在这里返回一个不为undefined的值})this.hooks.arch.tap('lesson2', function(name) {console.log('lesson2', name);})}start() {this.hooks.arch.call('jay');}}let l = new Lesson();l.tap();l.start();
打印结果为: 
源码实现:
class SyncBailHook {constructor(args) {this.tasks = [];}tap(name, task) {this.tasks.push(task);}call(...args) {let ret; // 当前函数返回值let index = 0;do {ret = this.tasks[index++](...args);} while (ret === undefined && this.tasks.length > index);}}
同步流式钩子SyncWaterfallHook
可以接收到上一个函数的返回结果作为参数传入到下一个函数中去
const { SyncWaterfallHook } = require('./tapable/lib/index.js');class Lesson {constructor(props) {// 创建钩子this.hooks = {arch: new SyncWaterfallHook(['name']),}}tap() {this.hooks.arch.tap('lesson1', function(name) {console.log('lesson1', name);return 'lesson1 result'; // 返回lesson1结果})this.hooks.arch.tap('lesson2', function(data) { // data作为传参接受lesson1结果console.log('lesson2', data);})}start() {this.hooks.arch.call('jay');}}let l = new Lesson();l.tap();l.start();

源码实现:
class SyncWaterfallHook {constructor(args) {this.tasks = [];}tap(name, task) {this.tasks.push(task);}call(...args) {const [first, ...other] = this.tasks;const ret = first(...args);other.reduce((prev, next) => next(prev), ret);}}const hook = new SyncWaterfallHook(['name']);hook.tap('lesson1', function (name) {console.log('lesson1', name);return 'lesson1 result'})hook.tap('lesson2', function (data) {console.log('lesson2', data);})hook.call('jay');
同步循环钩子SyncLoopHook
可以手动指定上一个函数的执行次数, 直到上个函数返回undefined才执行下一个函数
这个方法在webpack中并没有用到
const { SyncLoopHook } = require('./tapable/lib/index.js');class Lesson {constructor(props) {// 创建钩子this.hooks = {arch: new SyncLoopHook(['name']),}this.counter = 0;}tap() {this.hooks.arch.tap('lesson1', name => {console.log('lesson1', name);return ++this.counter === 3 ? undefined : 'continue'; // 循环3次lesson1})this.hooks.arch.tap('lesson2', data => {console.log('lesson2', data);})}start() {this.hooks.arch.call('jay');}}let l = new Lesson();l.tap();l.start();

源码实现:
class SyncLoopHook {constructor(args) {this.tasks = [];}tap(name, task) {this.tasks.push(task);}call(...args) {this.tasks.forEach(task => {let ret;do {ret = task(...args);} while (ret !== undefined);});}}let counter = 0;const hook = new SyncLoopHook(["name"]);hook.tap("lesson1", function(name) {console.log("lesson1", name);return ++counter === 3 ? undefined : "continue";});hook.tap("lesson2", function(data) {console.log("lesson2", data);});hook.call("jay");
