Sync
SyncHook
使用
const { SyncHook } = require('tapable')
class Lesson {
constructor() {
this.hooks = {
arch: new SyncHook(['arch'])
}
}
tap() {
this.hooks.arch.tap('a', function(name) {
console.log('node', name)
})
this.hooks.arch.tap('b', function(name) {
console.log('react', name)
})
}
start() {
this.hooks.arch.call('world')
}
}
var a = new Lesson()
a.tap()
a.start()
原理
class SyncHook {
constructor() {
this.tasks = []
}
tap(name, task) {
this.tasks.push(task)
}
call(...args) {
this.tasks.forEach(item => {
item.task.call(null, ...args)
})
}
}
SyncBailHook
使用
const { SyncBailHook } = require('tapable')
class Lesson {
constructor() {
this.hooks = {
arch: new SyncBailHook(['arch', 'a'])
}
}
tap() {
this.hooks.arch.tap('a', function(name) {
console.log('node', name)
return 0
})
this.hooks.arch.tap('b', function(name) {
console.log('react', name)
})
}
start() {
this.hooks.arch.call('world')
}
}
var a = new Lesson()
a.tap()
a.start()
原理
class SyncBailHook {
constructor() {
this.tasks = []
}
tap(name, task) {
this.tasks.push(task)
}
call(...args) {
let res = true
let i = 0
do {
res = this.tasks[i++].call(null, ...args)
} while (i < this.tasks.length && res === undefined)
}
}
SyncWaterfallHook
使用
const { SyncWaterfallHook } = require('tapable')
class Lesson {
constructor() {
this.hooks = {
arch: new SyncWaterfallHook(['arch', 'a'])
}
}
tap() {
this.hooks.arch.tap('a', function(name) {
console.log('node', name)
return '返回数据作为下一个事件的参数(如果返回undefined的话,等同于没有返回,不做处理 )'
})
this.hooks.arch.tap('b', function(data) {
console.log('react', data)
})
}
start() {
this.hooks.arch.call('world')
}
}
var a = new Lesson()
a.tap()
a.start()
原理
class SyncWaterfallHook {
constructor() {
this.tasks = []
}
tap(name, task) {
this.tasks.push(task)
}
call(...args) {
const [first, ...others] = this.tasks
const ret = first(...args)
others.reduce((a, b) => {
if (a === undefined) {
return b(...args)
} else {
return b(a)
}
}, ret)
}
}
SyncLoopHook
使用
const { SyncLoopHook } = require('tapable')
class Lesson {
constructor() {
this.index = 0
this.hooks = {
arch: new SyncLoopHook(['arch', 'a'])
}
}
tap() {
this.hooks.arch.tap('a', (name) => {
console.log('node', name)
return ++this.index === 3 ? undefined : '继续学'
})
this.hooks.arch.tap('b', function(name) {
console.log('react', name)
})
}
start() {
this.hooks.arch.call('world')
}
}
var a = new Lesson()
a.tap()
a.start()
原理
class SyncLoopHook {
constructor() {
this.tasks = []
}
tap(name, task) {
this.tasks.push(task)
}
call(...args) {
let index = 0
let ret
do {
ret = this.tasks[index](...args)
if (ret === undefined) {
index++
}
} while (index < this.tasks.length)
}
}
Async
AsyncParallelHook
使用
const { AsyncParallelHook } = require('tapable')
class Lesson {
constructor() {
this.hooks = {
arch: new AsyncParallelHook(['arch'])
}
}
tap() {
this.hooks.arch.tapAsync('a', (name, cb) => {
setTimeout(() => {
console.log('node', name)
cb()
}, 2000)
})
this.hooks.arch.tapAsync('b', (name, cb) => {
setTimeout(() => {
console.log('react', name)
cb()
}, 1000)
})
}
start() {
this.hooks.arch.callAsync('world', function() {
console.log('end')
})
}
}
var a = new Lesson()
a.tap()
a.start()
原理-tapAsync
class AsyncParallelHook {
constructor() {
this.tasks = []
}
tapAsync(name, task) {
this.tasks.push({
name,
task
})
}
callAsync(...args) {
const cb = args.pop()
let index = 0
const done = () => {
index++
if (index === this.tasks.length) {
cb()
}
}
this.tasks.forEach(item => {
item.task(...args, done)
})
}
}
原理-tapPromise
class AsyncParallelHook {
constructor() {
this.tasks = []
}
tapPromise(name, task) {
this.tasks.push({
name,
task
})
}
promise(...args) {
const tasks = this.tasks.map(task => task(...args))
return Promise.all(tasks)
}
}
class Lesson {
constructor() {
this.hooks = {
arch: new AsyncParallelHook(['arch', 'a'])
}
}
tap() {
this.hooks.arch.tapPromise('a', (name) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('node', name)
resolve()
}, 2000)
})
})
this.hooks.arch.tapPromise('react', (name, cb) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('react', name)
resolve()
}, 2000)
})
})
}
start() {
this.hooks.arch.promise('world').then(() => {
console.log('end')
})
}
}
var a = new Lesson()
a.tap()
a.start()
AsyncParallelBailHook
使用
const { AsyncParallelBailHook } = require('tapable')
class Lesson {
constructor() {
this.hooks = {
arch: new AsyncParallelBailHook(['arch'])
}
}
tap() {
this.hooks.arch.tapPromise('a', (name) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('node', name)
reject('wrong')
}, 1000)
})
})
this.hooks.arch.tapPromise('b', (name) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('react', name)
resolve()
}, 2000)
})
})
}
start() {
this.hooks.arch.promise('world').then(() => {
console.log('success')
}).catch(() => {
console.log('fail')
})
}
}
var a = new Lesson()
a.tap()
a.start()
原理
AsyncSeriesHook
使用
const { AsyncSeriesHook } = require('tapable')
class Lesson {
constructor() {
this.hooks = {
arch: new AsyncSeriesHook(['arch'])
}
}
tap() {
this.hooks.arch.tapAsync('a', (name, cb) => {
setTimeout(() => {
console.log('node', name)
cb()
}, 1000)
})
this.hooks.arch.tapAsync('b', (name, cb) => {
setTimeout(() => {
console.log('react', name)
cb()
}, 1000)
})
}
start() {
this.hooks.arch.callAsync('world', function() {
console.log('end')
})
}
}
var a = new Lesson()
a.tap()
a.start()
原理-tapAsync/callAsync
class AsyncSeriesHook {
constructor() {
this.tasks = []
}
tapAsync(name, task) {
this.tasks.push(task)
}
callAsync(...args) {
const fn = args.pop()
let index = 0
const next = () => {
if (this.tasks.length === index) return fn()
const task = this.tasks[index++]
task(...args, next)
}
next()
}
}
原理tapPromise/promise
class AsyncSeriesHook {
constructor() {
this.tasks = []
}
tapPromise(name, task) {
this.tasks.push(task)
}
promise(...args) {
const [first, ...others] = this.tasks
return others.reduce((p, n) => {
return p.then(() => n(...args))
}, first(...args))
}
}
AsyncSeriesWaterfallHook
使用
const { AsyncSeriesWaterfallHook } = require('tapable')
class Lesson {
constructor() {
this.hooks = {
arch: new AsyncSeriesWaterfallHook(['arch'])
}
}
tap() {
this.hooks.arch.tapAsync('a', (name, cb) => {
setTimeout(() => {
console.log('node', name)
cb()
}, 2000)
})
this.hooks.arch.tapAsync('b', (name, cb) => {
setTimeout(() => {
console.log('react', name)
cb()
}, 1000)
})
}
start() {
this.hooks.arch.callAsync('world', function() {
console.log('end')
})
}
}
var a = new Lesson()
a.tap()
a.start()
原理
class AsyncSeriesWaterfallHook {
constructor() {
this.tasks = []
}
tapAsync(name, task) {
this.tasks.push(task)
}
callAsync(...args) {
const fn = args.pop()
let index = 0
const next = (err, data) => {
const task = this.tasks[index]
if (!task || err === 'error') return fn()
if (index === 0) {
task(data, next)
} else {
task(data, next)
}
index++
}
next(null, ...args)
}
}