tapable 本質上是一種事件流的機制,幫助咱們將各個插件串聯起來 包含(發佈訂閱模式)promise
let { SyncHook } = require('tapable')
class Animals {
constructor() {
this.hooks = {
mam: new SyncHook(['name'])
}
}
tap() {
this.hooks.mam.tap('cat', function (name) {
console.log('cat', name)
})
this.hooks.mam.tap('dog', function (name) {
console.log('dog', name)
})
}
start() {
this.hooks.mam.call('mam')
}
}
let animals = new Animals()
animals.tap() // 訂閱方法
animals.start() // 發佈
複製代碼
class SyncHook {
constructor(args) {
this.tasks = []
}
tap(name, task) {
this.tasks.push(task)
}
call(...args) {
this.tasks.forEach((task) => {
task(...args)
})
}
}
let hook = new SyncHook(['name'])
hook.tap('cat',function(name){
console.log('cat', name)
})
hook.tap('dog',function(name){
console.log('dog', name)
})
hook.call('mam')
// dog mam
// cat mam
複製代碼
串行同步執行,有一個返回值不爲undefined就跳過剩下邏輯, bail是保險的意思,表示有一個出錯就不往下執行了bash
let { SyncBailHook } = require('tapable')
class Animals {
constructor() {
this.hooks = {
mam: new SyncBailHook(['name'])
}
}
tap() {
this.hooks.mam.tap('cat', function (name) {
console.log('cat', name)
return '喵喵叫' // 返回了一個非 undefined值 不繼續執行
})
this.hooks.mam.tap('dog', function (name) {
console.log('dog', name)
})
}
start() {
this.hooks.mam.call('mam')
}
}
let animals = new Animals()
animals.tap()
animals.start()
// cat mam
複製代碼
class SyncBailHook {
constructor(args) {
this.tasks = []
}
tap(name, task) {
this.tasks.push(task)
}
call(...args) { // 循環全部訂閱tasks,若是有一個函數的返回值不爲undefined跳出循環,以後的函數都不執行
let ret
let index = 0
do{
ret = this.tasks[index++](...args)
}while(ret === undefined && index<this.tasks.length)
}
}
let hook = new SyncBailHook(['name'])
hook.tap('cat',function(name){
console.log('cat', name)
return 'miao'
})
hook.tap('dog',function(name){
console.log('dog', name)
})
hook.call('mam')
複製代碼
就想水流動同樣,下一個任務能夠獲得上一個任務的返回值異步
let { SyncWaterfallHook } = require('tapable')
class Animals {
constructor() {
this.hooks = {
mam: new SyncWaterfallHook(['name'])
}
}
tap() {
this.hooks.mam.tap('cat', function (name) {
console.log('cat', name)
return 'eat food'
})
this.hooks.mam.tap('dog', function (name) {
console.log('dog', name)
})
}
start() {
this.hooks.mam.call('mam')
}
}
let animals = new Animals()
animals.tap()
animals.start()
// cat mam
// dog eat food
複製代碼
class SyncWaterfallHook {
constructor(args) {
this.tasks = []
}
tap(name, task) {
this.tasks.push(task)
}
call(...args) {
let [first,...others] = this.tasks
let ret = first() // 結構出當前第一個函數執行
others.reduce((pre, next) => {
return next(pre)
}, ret)
// ret傳入reduce,至關於第一次循環pre等於ret,執行下一個函數後返回值等於第二次循環pre。這樣每次循環pre都有返回值
}
}
let hook = new SyncWaterfallHook(['name'])
hook.tap('cat',function(name){
console.log('cat', name)
return 'eat food'
})
hook.tap('dog',function(name){
console.log('dog', name)
})
hook.call('mam')
// cat undefined
// dog eat food
複製代碼
tap: 同步註冊 tapAsync: 異步註冊 tapPromise: 註冊時promise函數
call callAsync promiseui