webpack之tapable
webpack
tapable
webpack本质上是一种事件流的机制,它的工作流程就是将各个插件串联起来,而实现这一切的核心就是tapable,核心原理是依赖于发布订阅模式;
tapable注册函数的方法有三种:tap、tapAsync、tapPromise
相对应的执行方法也有三种:call、callAsync、promise
SyncHook
const { SyncLoopHook } = require(‘tapable‘) class Lesson { constructor () { this.index = 0 this.hooks = { arch: new SyncLoopHook([‘name‘]) } } tap () { let self = this this.hooks.arch.tap(‘node‘, function (name) { console.log(‘node‘, name) return ++self.index >=3 ? undefined :‘23‘ }) this.hooks.arch.tap(‘react‘, function (name) { console.log(‘react‘, name) }) } start () { this.hooks.arch.call(‘jw‘) } } let l = new Lesson() l.tap() l.start()
- SyncBailHook
SyncBailHook同步熔断保险钩子,即return一个非undefined的值,则不再继续执行后面的监听函数
- SyncWaterfallHook
上一个监听函数的返回值会传递给下一个监听函数
- SyncLoopHook
遇到某个不返回undefined的监听函数,就重复执行
AsyncHook
const { AsyncParallelHook } = require(‘tapable‘) class Lesson { constructor () { this.index = 0 this.hooks = { arch: new AsyncParallelHook([‘name‘]) } } tap () { let self = this this.hooks.arch.tapAsync(‘node‘, function (name, cb) { setTimeout(() => { console.log(‘node‘, name) cb() }) }) this.hooks.arch.tapAsync(‘react‘, function (name, cb) { console.log(‘react‘, name) cb() }) } start () { this.hooks.arch.callAsync(‘jw‘, function () { console.log(‘end‘) }) } } let l = new Lesson() l.tap() l.start() 结果: react jw node jw end
- AsyncParallelHook
异步 并行
源码:
module.exports = class AsyncParallelHook { constructor () { this.tasks = [] } tapAsync (name, fn) { this.tasks.push(fn) } callAsync (...args) { const final = args.pop() let index = 0 const done = () => { index++ if (index === this.tasks.length) { final() } } this.tasks.forEach(task => { task(...args, done) }) } }
- AsyncSeriesHook
异步串行
源码:
// callback方式 module.exports = class AsyncSerieslHook { constructor () { this.tasks = [] } tapAsync (name, fn) { this.tasks.push(fn) } callAsync (...args) { let index = 0 const final = args.pop() const next = () => { if (this.tasks.length === index) { final() return } const firstFn = this.tasks[index++] firstFn(...args, next) } next() } } // promise方式 module.exports = class AsyncSerieslHook { constructor () { this.tasks = [] } tapPromise (name, fn) { this.tasks.push(fn) } promise (...args) { const [firstFn, ...others] = this.tasks return others.reduce((n, p) => { return n.then(_ => p(...args)) }, firstFn(...args)) } }
调用:
//callback方式调用 const AsyncSeriesHook = require(‘./asyncHook‘) class Lesson { constructor () { this.index = 0 this.hooks = { arch: new AsyncSeriesHook([‘name‘]) } } tap () { this.hooks.arch.tapAsync(‘node‘, function (name, cb) { setTimeout(() => { console.log(‘node‘, name) cb() }, 1000) }) this.hooks.arch.tapAsync(‘react‘, function (name, cb) { setTimeout(() => { console.log(‘react‘, name) cb() }, 2000) }) } start () { this.hooks.arch.callAsync(‘jw‘, function () { console.log(‘end‘) }) } } let l = new Lesson() l.tap() l.start() // promise方式调用 const AsyncSeriesHook = require(‘./asyncHook‘) class Lesson { constructor () { this.index = 0 this.hooks = { arch: new AsyncSeriesHook([‘name‘]) } } tap () { this.hooks.arch.tapPromise(‘node‘, function (name) { return new Promise((resolve, reject) => { setTimeout(() => { console.log(‘node‘, name) resolve() }, 1000) }) }) this.hooks.arch.tapPromise(‘react‘, function (name) { return new Promise((resolve, reject) => { setTimeout(() => { console.log(‘react‘, name) resolve() }, 2000) }) }) } start () { this.hooks.arch.promise(‘jw‘).then(function () { console.log(‘end‘) }) // this.hooks.arch.callAsync(‘jw‘, function () { // console.log(‘end‘) // }) } } let l = new Lesson() l.tap() l.start()
相关推荐
不知道该写啥QAQ 2020-11-12
webfullStack 2020-11-09
Yvettre 2020-09-15
想做大牛的蜗牛 2020-10-30
gloria0 2020-10-26
gaojie0 2020-09-11
SelinaChan 2020-08-14
不知道该写啥QAQ 2020-08-09
gloria0 2020-08-09
不知道该写啥QAQ 2020-08-02
hline 2020-07-29
SelinaChan 2020-07-28
wangdianyong 2020-07-23
webpackvuees 2020-07-23
yqoxygen 2020-07-20
不知道该写啥QAQ 2020-07-18
waterv 2020-07-18
81463166 2020-07-17