webpack之tapable
2021-02-13 08:17
标签:方法 也有 OLE lock ISE 钩子 rom 并行 nal webpack本质上是一种事件流的机制,它的工作流程就是将各个插件串联起来,而实现这一切的核心就是tapable,核心原理是依赖于发布订阅模式; SyncBailHook同步熔断保险钩子,即return一个非undefined的值,则不再继续执行后面的监听函数 上一个监听函数的返回值会传递给下一个监听函数 遇到某个不返回undefined的监听函数,就重复执行 异步 并行 源码: 异步串行 源码: 调用: webpack之tapable 标签:方法 也有 OLE lock ISE 钩子 rom 并行 nal 原文地址:https://www.cnblogs.com/raind/p/13020567.htmlwebpack
tapable
tapable注册函数的方法有三种:tap、tapAsync、tapPromise
相对应的执行方法也有三种:call、callAsync、promiseSyncHook
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()
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
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)
})
}
}
// 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()
下一篇:每天坚持一个CSS——社会人