分析webpack中使用的Tapable——异步钩子实现及模拟实现

本文深入探讨了webpack核心组件Tapable,重点关注其异步钩子的使用和原理。从AsyncParallelHook、AsyncSeriesHook到AsyncSeriesWaterfallHook,通过实例展示了如何以Promise方式实现这些异步钩子,揭示了Tapable如何协调插件的同步和异步执行,以及其在事件流机制中的关键作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

tapable
webpack本质上是一种事件流的机制,他的工作流程就是将各个插件串联起来,而实现这一切的核心就是tapable,

tapable有点类似于nodejs的events库,核心原理也是依赖于发布订阅模式:

继承了很多插件,同步的和异步的

tapable库中有3中注册方法 tap(同步注册)、tabAsync(回调cb)、tabPromise(注册是promise)

调用的三种方法 call、 callAsync、 promise

tapable异步钩子使用及原理

本章讲述异步钩子
异步钩子又分为异步并行和异步串行钩子:

AsyncParralleHook

当所有异步事件并行执行完成后,执行回调函数

使用方法:

// 异步钩子,串行、并行(需要等待所有并发的异步事件执行后再执行回调方法)
let {
   AsyncParallelHook} = require('tapable');
class Lesson {
   
    constructor() {
   
        this.index = 0;
        this.hooks = {
   
            arch: new AsyncParallelHook(['name']),
        }
    }
    // 注册监听函数(注册方法分为tap, tapAsync)
    tap() {
   
        this.hooks.arch.tapAsync('node', (name, cb) => {
   
            setTimeout(() => {
   
                console.log('node', name);
                cb();
            }, 1000);
        });
        this.hooks.arch.tapAsync('react', (name, cb) => {
   
            setTimeout(() => {
   
                console.log('react', name);
                cb();
            }, 1000);
        });
    }
    start() {
   
        this.hooks.arch.callAsync('zhangfeng', function () {
   
            console.log('end');
        });
    }
}

let les = new Lesson();

les.tap(); // 注册这两个事件
les.start(); // 启动钩子
// => node zhangfeng
// => react node还需要加强学习

实现原理:

class AsyncParralleHook {
       // 钩子是同步的
    constructor(args) {
    // args => ['name']
        this.tasks = [];
    }
    callAsync(...args) {
   
        let finalCallback = args.pop();// 拿出最终的参数
        let index = 0;
        let done = () => {
      // 类似 Promise.all
            index ++;
            if (index === this.tasks.length) {
   
                finalCallback();
            }
        };
        this.tasks.forEach(task => {
   
            task(...args, done);
        });
    }
    tapAsync(name, task) {
   
        this.tasks.push(task);
    }
}

let hook = new AsyncParralleHook(['name']);

hook.tapAsync('react', function (name, cb) {
   
    setTimeout(() => {
   
        console.log('react', name);
        cb();
    }, 1000);
});

hook.tapAsync('node', function(name, cb) {
   
    setTimeout(() => {
   
        console.log('node', name);
        cb();
    }, 1000);
});

hook.callAsync('zhangfeng', function () {
   
    console.log('所有方法执行结束');
});

使用promise方式实现AsyncParallelHook

使

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值