1、Tapable 对外暴露了 9 种 Hooks 类,通过实例化来创建一个执行流程,并提供注册和执行方法
const {
SyncHook,
SyncBailHook,
SyncWaterfallHook,
SyncLoopHook,
AsyncParallelHook,
AsyncParallelBailHook,
AsyncSeriesHook,
AsyncSeriesBailHook,
AsyncSeriesWaterfallHook
} = require("tapable");
2、按同步、异步(串行、并行)分类
3、按执行模式分类
- Basic:执行每一个事件函数,不关心函数的返回值
- Bail:执行每一个事件函数,遇到第一个结果 result !== undefined 则返回,不再继续执行
- Waterfall:如果前一个事件函数的结果 result !== undefined,则 result 会作为后一个事件函数的第一个参数
- Loop:不停的循环执行事件函数,直到所有函数结果 result === undefined
4、使用案例
简单来说就是下面步骤
- 实例化构造函数 Hook
- 注册(一次或者多次)
- tap: 注册同步监听器。
- tapAsync: 注册异步监听器,使用回调函数。
- tapPromise: 注册异步监听器,使用 Promise。
- 执行(传入参数)
- call: 触发同步钩子。
- callAsync: 触发异步钩子,使用回调函数。
- promise: 触发异步钩子,返回 Promise。
- 如果有需要还可以增加对整个流程(包括注册和执行)的监听-拦截器
案例
const { SyncHook, AsyncParallelHook, WaterfallHook, AsyncSeriesHook } = require('tapable');
// SyncHook 示例
const syncHook = new SyncHook(['name']);
syncHook.tap('Listener1', (name) => {
console.log(`Hello ${name} from Listener1`);
});
syncHook.tap('Listener2', (name) => {
console.log(`Hello ${name} from Listener2`);
});
syncHook.call('Alice');
// AsyncParallelHook 示例
const asyncParallelHook = new AsyncParallelHook(['name']);
asyncParallelHook.tap('Listener1', (name, callback) => {
setTimeout(() => {
console.log(`Hello ${name} from Listener1`);
callback();
}, 1000);
});
asyncParallelHook.tapPromise('Listener2', async (name) => {
await new Promise((resolve) => setTimeout(resolve, 500));
console.log(`Hello ${name} from Listener2`);
});
asyncParallelHook.call('Bob', () => {
console.log('All listeners finished');
});
asyncParallelHook.promise('Bob').then(() => {
console.log('All listeners finished');
});
// WaterfallHook 示例
const waterfallHook = new WaterfallHook(['name']);
waterfallHook.tap('Listener1', (name) => {
console.log(`Hello ${name} from Listener1`);
return `${name} updated`;
});
waterfallHook.tap('Listener2', (name) => {
console.log(`Hello ${name} from Listener2`);
return `${name} final`;
});
const result = waterfallHook.call('Carol');
console.log(result);
// AsyncSeriesHook 示例
const asyncSeriesHook = new AsyncSeriesHook(['name']);
asyncSeriesHook.tap('Listener1', (name, callback) => {
setTimeout(() => {
console.log(`Hello ${name} from Listener1`);
callback();
}, 1000);
});
asyncSeriesHook.tapPromise('Listener2', async (name) => {
await new Promise((resolve) => setTimeout(resolve, 500));
console.log(`Hello ${name} from Listener2`);
});
asyncSeriesHook.call('Dave', () => {
console.log('All listeners finished');
});
asyncSeriesHook.promise('Dave').then(() => {
console.log('All listeners finished');
});