1、SyncHook
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('react',function (name) { console.log('react',name) }); hook.tap('node',function (name) { console.log('node',name) }); hook.call('dellyoung');
2、SyncWaterfallHook
class SyncWaterfallHook { // 钩子是同步的 constructor(args){ this.tasks = []; } tap(name,task){ this.tasks.push(task) } call(...args){ let [first,...others] = this.tasks; let ret = first(...args); others.reduce( (a,b)=>{ // a 上一个 b 下一个 return b(a); },ret ) } } // 绑定事件就是订阅 let hook = new SyncWaterfallHook(['name']); hook.tap('react',function (name) { console.log('react1',name); return 'reactOk' }); hook.tap('node',function (name) { console.log('node2',name); return 'nodeOk' }); hook.tap('webpack',function (name) { console.log('webpack',name) }); hook.call('dellyoung');
3、SyncLoopHook
class SyncLoopHook { // 钩子是同步的 // 只要返回不是undefined就会一直循环 constructor(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 hook = new SyncLoopHook(['name']); let total = 0; hook.tap('react',function (name) { console.log('react',name); return ++total === 3?undefined:'继续学' }); hook.tap('node',function (name) { console.log('node',name); }); hook.tap('webpack',function (name) { console.log('webpack',name) }); hook.call('dellyoung');
4、SyncBailHook
class SyncBailHook { // 钩子是同步的 constructor(args){ this.tasks = []; } tap(name,task){ this.tasks.push(task) } call(...args){ 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('react',function (name) { console.log('react1',name); // return '停止' }); hook.tap('node',function (name) { console.log('node2',name) }); hook.call('dellyoung');
1、AsyncParallelBailHook
类似promise.all[]
class AsyncParallelBailHook { // 钩子是同步的 // 只要返回不是undefined就会一直循环 constructor(args){ this.tasks = []; } tapAsync(name,task){ this.tasks.push(task) } callAsync(...args){ let finalCallBack = args.pop(); // 拿出最终的函数 let index = 0; let done = () => { index++; if(index === this.tasks.length){ finalCallBack(); } }; this.tasks.forEach(task=>{ task(...args,done) }) } } // 绑定事件就是订阅 let hook = new AsyncParallelBailHook(['name']); hook.tapAsync('react',function (name,callback) { setTimeout(()=>{ console.log('react',name); callback(); },5000 ); }); hook.tapAsync('node',function (name,callback) { setTimeout(()=>{ console.log('node',name); callback(); },1000 ); }); hook.callAsync('dellyoung',function () { console.log('newBegin') });promise版本的AsyncParallelBailHook
class AsyncParallelBailHook { // 钩子是同步的 // 只要返回不是undefined就会一直循环 constructor(args) { this.tasks = []; } tabPromise(name, task) { this.tasks.push(task) } promise(...args) { let tasks = this.tasks.map( (task) => { return task(...args) } ); // let tasks = this.tasks.map(task => task(...args)); return Promise.all(tasks); } } // 绑定事件就是订阅 let hook = new AsyncParallelBailHook(['name']); hook.tabPromise('react', function (name) { return new Promise( (resolve, reject) => { setTimeout(() => { console.log('react', name); resolve(); }, 1000 ); } ) }); hook.tabPromise('node', function (name) { return new Promise( (resolve, reject) => { setTimeout(() => { console.log('node', name); resolve(); }, 2000 ); } ) }); hook.promise('dellyoung').then(function () { console.log('newBegin') });
2、AsyncSeriesHook
异步串行
class AsyncSeriesHook { constructor(args) { this.tasks = []; } tabAsync(name, task) { this.tasks.push(task) } callAsync(...args) { let finalCallBack = args.pop(); let index = 0; let next = () => { if(this.tasks.length === index){ return finalCallBack(); } let task = this.tasks[index++]; task(...args, next); }; next(); } } // 绑定事件就是订阅 let hook = new AsyncSeriesHook(['name']); hook.tabAsync('react', function (name, callback) { setTimeout(() => { console.log('react', name); callback(); }, 3000 ); }); hook.tabAsync('node', function (name, callback) { setTimeout(() => { console.log('node', name); callback(); }, 1000 ) }); hook.callAsync('dellyoung',function () { console.log('newBegin') });promise版本的AsyncSeriesHook
class AsyncSeriesHook { constructor(args) { this.tasks = []; } tabPromise(name, task) { this.tasks.push(task) } promise(...args) { // 类redux源码 let [first,...other] = this.tasks; return other.reduce( (prom,n)=>{ return prom.then(()=>n(...args)) },first(...args) ) } } // 绑定事件就是订阅 let hook = new AsyncSeriesHook(['name']); hook.tabPromise('react', function (name) { return new Promise( (resolve, reject) => { setTimeout(() => { console.log('react', name); resolve(); }, 1000 ); } ) }); hook.tabPromise('node', function (name) { return new Promise( (resolve, reject) => { setTimeout(() => { console.log('node', name); resolve(); }, 1000 ); } ) }); hook.promise('dellyoung').then(function () { console.log('newBegin') });
转载于:https://www.cnblogs.com/piaobodewu/p/11261408.html
相关资源:浅谈Webpack核心模块tapable解析