1.SyncHook
/**
* 同步钩子
*/
class SyncHook{
constructor(args){
this.tasks = []
}
tap(name,task) {
this.tasks.push(task)
}
call(...args) {
this.tasks.forEach(task=>task(...args))
}
}
const hook = new SyncHook(['name'])
hook.tap('node',function(name){
console.log('node',name)
})
hook.tap('react',function(name){
console.log('react',name)
})
hook.call('cus')
2.SyncBailHook
/**
* 同步
* 如果第一个函数返回的不是undefined的话,就停止执行
*/
class SyncBailHook {
constructor(args) {
this.tasks = [];
}
tap(name, task) {
this.tasks.push(task)
}
call(...args) {
let index = 0;
let ret;
do {
ret = this.tasks[index++](...args)
} while (ret === undefined && index < this.tasks.length)
}
}
const hook = new SyncBailHook(['name']);
hook.tap('node', function (name) {
console.log('node', name)
return '打住吧'
})
hook.tap('react', function (name) {
console.log('react', name)
})
hook.call('cus')
3.SyncWaterfallHook
/**
* 瀑布流的同步钩子
*/
class SyncWaterfallHook {
constructor(args) {
this.tasks = [];
}
tap(name, task) {
this.tasks.push(task)
}
call(...args) {
const [first, ...others] = this.tasks;
others.reduce((prev, next) => {
return next(prev)
}, first(...args))
}
}
const hook = new SyncWaterfallHook(['name']);
hook.tap('node', function (name) {
console.log('node', name)
return 'node nice'
})
hook.tap('react', function (data) {
console.log('react', data);
return 'react ok'
})
hook.tap('webpack', function (data) {
console.log('webpack', data)
})
hook.call('cus')
4.SyncLoopHook
/**
* 可以限制循环次数的同步钩子
*/
class SyncLoopHook {
constructor(args) {
console.log(args)
this.tasks = []
}
tap(name, task) {
this.tasks.push(task)
}
call(...args) {
this.tasks.forEach(task => {
let ret;
do {
ret = task(...args)
} while (ret !== undefined)
})
}
}
let total = 0;
const hook = new SyncLoopHook(['name']);
hook.tap('node', function (name) {
console.log('node', name)
return ++total === 3 ? undefined : '1'
})
hook.tap('react',function(name){
console.log('react',name)
})
hook.call('cus')
5.AsyncParralleHook
/**
* 异步并行的钩子
*/
class AsyncParralleHook {
constructor(args) {
this.tasks = []
}
tapAsync(name, task) {
this.tasks.push(task)
}
callAsync(...args) {
console.log(args)
const finalCallback = args.pop()
let index = 0;
let done = () => {
index++;
if (index === this.tasks.length) finalCallback(...args);
}
this.tasks.forEach(task => task(...args, done))
}
}
const hook = new AsyncParralleHook(['name'])
hook.tapAsync('node', function (name, cb) {
setTimeout(() => {
console.log('node',name);
cb()
}, 1000)
});
hook.tapAsync('react', function (name, cb) {
setTimeout(() => {
console.log('react',name);
cb()
}, 1000)
});
hook.callAsync('cus', function (name) {
console.log('all',name)
})
6.AsyncParralleHook(promise版)
/**
* 异步并行的钩子promise版
*/
class AsyncParralleHook {
constructor(args) {
this.tasks = [];
}
tapPromise(name, task) {
this.tasks.push(task);
}
promise(...args) { // express 中的中间件的原理
let promises = this.tasks.map(task=>task(...args));
return Promise.all(promises)
}
}
const hook = new AsyncParralleHook(['name']);
hook.tapPromise('node', function (name) {
return new Promise((resolve,reject)=>{
setTimeout(() => {
console.log('node',name);
resolve();
}, 1000);
})
});
hook.tapPromise('react', function (name) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('react',name);
resolve();
}, 1000);
})
});
hook.promise('cus').then(function () {
console.log('all')
});
7.AsyncSeriesHook
/**
* 异步串行hook
*/
class AsyncSeriesHook {
constructor() {
this.tasks = []
}
tapPromise(name, task) {
this.tasks.push(task)
}
promise(...args) {
const [first, ...others] = this.tasks;
return others.reduce((prev, next) => {
return prev.then((name) => next(name))
}, first(...args))
}
}
const hook = new AsyncSeriesHook(['name'])
hook.tapPromise('node', function (name) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('node',name)
resolve(name)
}, 1000)
})
})
hook.tapPromise('react', function (name) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('react',name)
resolve(name)
}, 1000)
})
})
hook.promise('cus').then(function (name) {
console.log('all',name)
})