tapable钩子函数介绍

2021-03-03 14:13:13 浏览数 (1)

webpack的的实现是基于tapable,来看一下tabable的各个钩子函数的使用。

一、钩子类型

tapable提供了很多钩子(Hook classes)

代码语言:javascript复制
const {
	SyncHook,                    // 同步钩子 从上到下顺序执行
	SyncBailHook,                // 同步早退钩子 从上到下顺序执行,遇到返回值不是undefined的注册函数时停止执行
	SyncWaterfallHook,           // 同步瀑布钩子 从上到下执行,依次将返回值传递给下一个函数
	SyncLoopHook,                // 同步循环钩子 从上到下执行,某个函数可能会执行好几遍,当返回值是undefined会继续执行下个函数
	AsyncParallelHook,           // 异步并发钩子 异步并行
	AsyncParallelBailHook,       // 异步并发可早退钩子 异步并行熔断
	AsyncSeriesHook,             // 异步顺序钩子   异步串行
	AsyncSeriesBailHook,         // 异步顺序可早退钩子 异步串行熔断
	AsyncSeriesWaterfallHook     // 异步顺序瀑布钩子   异步串行值传递【瀑布】
 } = require("tapable");
复制代码

二、钩子使用方法

3.1 同步钩子-SyncHook
代码语言:javascript复制
import { SyncHook } from 'tapable';

const hook = new SyncHook(); // 创建钩子对象
hook.tap('logPlugin', () => console.log('注册了')); // tap方法注册钩子回调
hook.call(); // call方法调用钩子,打印出‘被勾了’三个字
复制代码
3.2 同步早退钩子-SyncBailHook

SyncBailHook就是根据每一步返回的值来决定要不要继续往下走,如果return了一个非undefined的值 那就不会往下走,注意 如果什么都不return 也相当于return了一个undefined。

代码语言:javascript复制
import { SyncBailHook } from 'tapable';

const hook = new SyncBailHook();
hook.tap('SyncBailHook1', () => console.log(`钩子1`));
hook.tap('SyncBailHook2', () => {console.log(`钩子2`) ; return 1});
hook.tap('SyncBailHook3', () => console.log(`钩子3`));

hook.call(); // 会打印‘钩子1’‘钩子2’‘钩子3’
复制代码
3.3 同步瀑布钩子-SyncWaterfallHook

它的每一步都依赖上一步的执行结果,也就是上一步return的值就是下一步的参数。

代码语言:javascript复制
import { SyncWaterfallHook  } from 'tapable';

const hook = new SyncWaterfallHook(["newSpeed"]);
hook.tap('SyncWaterfallHook1', (speed) => { console.log(`增加到${speed}`); return speed   100; });
hook.tap('SyncWaterfallHook2', (speed) => { console.log(`增加到${speed}`); return speed   50; });
hook.tap('SyncWaterfallHook3', (speed) => { console.log(`增加到${speed}`); });

hook.call(50); // 打印‘增加到50’‘增加到150’‘增加到200’
复制代码
3.4 同步循环钩子 -SyncLoopHook

SyncLoopHook是同步的循环钩子,它的插件如果返回一个非undefined。就会一直执行这个插件的回调函数,直到它返回undefined。

代码语言:javascript复制
import { SyncLoopHook } from 'tapable';

let index = 0;
const hook = new SyncLoopHook();
hook.tap('startPlugin1', () => {
    console.log(`执行`);
    if (index < 5) {
        index  ;
        return 1;
    }
}); 

hook.tap('startPlugin2', () => {
    console.log(`执行2`);
});

hook.call(); // 打印‘执行’6次,打印‘执行2’一次。
复制代码
3.5异步并发钩子-AsyncParallelHook

当所有的异步任务执行结束后,再最终的回调中执行接下来的代码

代码语言:javascript复制
import { AsyncParallelHook } from 'tapable';

const hook = new AsyncParallelHook();
hook.tapAsync('calculateRoutesPlugin1', (callback) => {
    setTimeout(() => {
        console.log('异步事件1');
        callback();
    }, 1000);
});

hook.tapAsync('calculateRoutesPlugin2', (callback) => {
    setTimeout(() => {
        console.log('异步事件2');
        callback();
    }, 2000);
});

hook.callAsync(() => { console.log('最终的回调'); }); // 会在1s的时候打印‘异步事件1’。2s的时候打印‘异步事件2’。紧接着打印‘最终的回调’
复制代码
3.6异步并发可早退钩子-AsyncParallelBailHook
代码语言:javascript复制
import { AsyncParallelBailHook } from 'tapable';

const hook = new AsyncParallelBailHook();
hook.tapAsync('calculateRoutesPlugin1', (callback) => {
    setTimeout(() => {
        console.log('异步事件1');
        callback(1);
    }, 1000);
});

hook.tapAsync('calculateRoutesPlugin2', (callback) => {
    setTimeout(() => {
        console.log('异步事件2');
        callback();
    }, 2000);
});

hook.callAsync((result) => { console.log('最终的回调',result); }); // 会在1s的时候打印‘异步事件1’,紧接着打印‘最终的回调’,2s的时候打印‘异步事件2’。
复制代码
3.7 异步顺序钩子- AsyncSeriesHook
代码语言:javascript复制
import { AsyncSeriesHook } from 'tapable';

const hook = new AsyncSeriesHook();
hook.tapPromise('calculateRoutesPlugin1', () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log('异步事件1');
            resolve();
        }, 1000);
    });
});

hook.tapPromise('calculateRoutesPlugin2', () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log('异步事件2');
            resolve();
        }, 2000);
    });
});

hook.then(() => { console.log('最终的回调'); });
// 1s过后,打印异步事件1,再过2s(而不是到了第2s,而是到了第3s),打印异步事件2,再立马打印最终的回调。
复制代码
3.8 异步顺序可早退钩子-AsyncSeriesBailHook
代码语言:javascript复制
import { AsyncSeriesBailHook } from 'tapable';

const hook = new AsyncSeriesBailHook();
hook.tapPromise('calculateRoutesPlugin1', () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log('异步事件1');
            resolve(1);
        }, 1000);
    });
});

hook.tapPromise('calculateRoutesPlugin2', () => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log('异步事件2');
            resolve();
        }, 2000);
    });
});

hook.then(() => { console.log('最终的回调'); });
// 1s过后,打印异步事件1,立马打印最终的回调,不会再执行异步事件2了。
复制代码
3.9 异步顺序瀑布钩子-AsyncSeriesWaterfallHook
代码语言:javascript复制
import { AsyncSeriesWaterfallHook } from 'tapable';

const hook = new AsyncSeriesWaterfallHook(['args']);
hook.tapPromise('calculateRoutesPlugin1', (result) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log('异步事件1', result);

            resolve(result 1);
        }, 1000);
    });
});

hook.tapPromise('calculateRoutesPlugin2', (result) => {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log('异步事件2', result);
            resolve(result 2);
        }, 2000);
    });
});

hook.promise(12).then((result) => { console.log('最终的回调'   result); });
// // 1s过后,打印异步事件1 12,再过2s打印异步事件2 13,然后立马打印最终的回调 15。

希望对你有所帮助

参考https://juejin.cn/post/6900095458409414669

0 人点赞