webpack 里面使用的
Tapable
webpack 是一种事件流机制,将各个插件串联起来,wbpack 使用 Tapable 进行编译
- 安装
1 | yarn add apable |
同步钩子 SyncHook
- 使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23let { SyncHook } = require('tapable');
class Lesson{
constructor(){
this.hooks={
arch: new SyncHook(['name])
}
}
tap(){//注册监听函数
this.hooks.arch.tap('node',function(){
console.log('node',name)
})
this.hooks.arc.tap('node',function(){
console.log('node',name)
})
}
start(){
this.hooks.arch.call('fdd')
}
}
let l =new Lesson()
l.tap() //注册钩子
l.start() //启动钩子- SyncHook 实现原理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19class SyncHook{
constructor(args){ // args =》['name']
this.tasks=[]
}
tap(name, task){
this.task.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('fdd')SyncBailHook 可熔断钩子 return 非 undefined 的值就停止向下执行
- 使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24let { SyncBailHook } = require('tapable')
class Lesson{
constructor(){
this.hooks = {
arch: new SyncBailHook(['name'])
}
}
tap(){ //注册监听函数
this.hooks.arch.tap('node',function(name){
console.log('node',name)
return '停止学习'
})
this.hooks.arch.tap('React',function(name){
console.log('React',name)
})
}
start(){
this.hooks.arch.call('fdd')
}
}
let l =new Lesson()
l.tap() //注册钩子
l.start() //启动钩子- SyncBailHook 实现原理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23class SyncBailHook{
constructor(arg){
this.tasks=[]
}
tap(name,task){
this.tasks.push(task)
}
call(...args){
let ret; //当前task的返回值
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('React',name)
})
hook.tap('node',function(name){
console.log('node',name)
})
hook.call('fdd')SyncWaterfallHook 瀑布流钩子
- 使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23let { SyncWaterfallHook } = require('tapable');
class Less{
constructor(){
this.hooks={
arch: new SyncWaterfallHook(['name'])
}
}
tap(name, task){
this.hooks.arch.tap('node', function(name){
console.log('node', name);
return 'node学习'
})
this.hooks.arch.tap('React',function(data){
console.log('React',data)
})
}
start(){
this.hooks.arch.call('fdd')
}
let l =new Lesson()
l.tap() //注册钩子
l.start() //启动钩子
}- SyncWaterfallHook 实现原理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25class SyncWaterfallHook{
constructor(args){
this.tasks=[]...args
}
tap(name, task){
this.tasks.push(task)
}
call(...args){
let [ first, ...others] = this.tasks;
let ret = first(...args)
others.reduce((a, b) => b(a),ret) /将a的结果传递给b,初始值为第一个函数的执行结果
}
}
let hook= new SyncWaterfallHook(['name']);
hook.tap('React', function(name){
console.log('React', name);
return 'ReactOk'
})
hook.tap('node', function(data){
console.log('node', data)
})
hook.tap('webpack', function(data){
console.log('webpack', data)
})
hook.call('fdd')SyncLoopHook 同步遇到某个不返回 undefinedj 的监听函数循环执行
- 使用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24let { SyncLoopHook } = require('tapable');
class Less{
constructor(){
this.index=0;
this.hooks={
arch: new SyncLoopHook(['name'])
}
}
tap(name, task){
this.hooks.arch.tap('node',(name) =>{
console.log('node', name);
return index++===3?return undefined: 'node学习'
})
this.hooks.arch.tap('React',(data) =>{
console.log('React',data)
})
}
call(){
this.hooks.arch.call('fdd')
}
let l =new Lesson()
l.tap() //注册钩子
l.start() //启动钩子
}- SyncLoopHook 实现原理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29class SyncLoopHook{
constructor(args){
this.tasks=[]...args
}
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:'ReactOk'
})
hook.tap('node', function(name){
console.log('node', name)
})
hook.tap('webpack', function(name){
console.log('webpack', name)
})
hook.call('fdd')AsyncParallelHook 异步并行
异步的钩子,并行执行,同发送多了请求,需要等待所有并发异步时间执行后再执行回调方法
注册方法 tap 和 tapAsync,tapPromise使用 异步注册 tapAsync
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30let { AsyncParallelHook } = require('tapable');
class Less{
constructor(){
this.hooks={
arch: new AsyncParallelHook(['name'])
}
}
tap(name, task){
this.hooks.arch.tapAsync('node', (name, cb)=>{
setTimeout(() => {
console.log('node', name);
cb()
},1000)
})
this.hooks.arch.tapAsync('React',(name, cb)=>{
setTimeout(() => {
console.log('React', name);
cb()
},1000)
})
}
start(){
this.hooks.arch.callAsync('fdd',function(){
console.log('end')
})
}
let l =new Lesson()
l.tap() //注册钩子
l.start() //启动钩子
}- AsyncParallelHook 实现原理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37class AsyncParallelHook{
constructor(args){
this.tasks=[]...args
}
tap(name, task){
this.tasks.push(task)
}
call(...args){
let finalCallback=args.pop() //拿到最后的回调函数
let index = 0;
let next = () => {
index++;
if(index===this.tasks.length){
finalCallback()
}
}
this.tasks.forEach(task => {
task(...args, done)
} )
}
}
let hook= new AsyncParallelHook(['name']);
hook.tapAsync('React', (name,cb) =>{
setTimeout(() => {
console.log('React', name);
cb()
},1000)
})
hook.tapAsync('node', (name,cb) => {
setTimeout(() => {
console.log('node', name);
cb()
},1000)
})
hook.callAsync('fdd',function(){
console.log('end')
})使用 promise 注册 tapPromise
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30let { AsyncParallelHook } = require('tapable');
class Less{
constructor(){
this.hooks={
arch: new AsyncParallelHook(['name'])
}
}
tap(name, task){
this.hooks.arch.tapPromise('node', (name)=>{
return new Promise((resolve,reject) => {
console.log('node', name);
resolve()
})
})
this.hooks.arch.tapPromise('React',(name)=>{
return new Promise((resolve,reject) => {
console.log('React', name);
resolve()
})
})
}
start(){
this.hooks.arch.promise('fdd').then(function(){
console.log('end')
})
}
let l =new Lesson()
l.tap() //注册钩子
l.start() //启动钩子
}AsyncParallelHook promise 注册 实现原理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29class AsyncParallelHook{
constructor(args){
this.tasks=[]...args
}
tapPromise(name, task){
this.tasks.push(task)
}
promise(...args){
let tasks= this.tasks.map(task =>task(...args))
return Promise.all(tasks)
}
}
let hook= new SyncWaterfallHook(['name']);
hook.tapPromise('React', (name) =>{
return new Promise((resolve,reject) =>
console.log('React', name);
resolve()
})
})
hook.tapPromise('node', (name) => {
return new Promise((resolve,reject) =>
console.log('node', name);
resolve()
})
})
hook.promise('fdd').then(function(){
console.log('end')
})
AsyncSeriesHook 异步串行
- 使用 异步注册 tapAsync
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30let { AsyncSeriesHook } = require('tapable');
class Less{
constructor(){
this.hooks={
arch: new AsyncSeriesHook(['name'])
}
}
tap(name, task){
this.hooks.arch.tapAsync('node', (name, cb)=>{
setTimeout(() => {
console.log('node', name);
cb()
},1000)
})
this.hooks.arch.tapAsync('React',(name, cb)=>{
setTimeout(() => {
console.log('React', name);
cb()
},1000)
})
}
start(){
this.hooks.arch.callAsync('fdd',function(){
console.log('end')
})
}
let l =new Lesson()
l.tap() //注册钩子
l.start() //启动钩子
}- AsyncSeriesHook 实现原理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36class AsyncSeriesHook{
constructor(args){
this.tasks=[]...args
}
tap(name, task){
this.tasks.push(task)
}
call(...args){
let finalCallback=args.pop() //拿到最后的回调函数
let index = 0;
let next = () => {
if(index===this.tasks.length){
return finalCallback()
}
let task = this.tasks[index++];
task(...args, next)
}
next()
}
}
let hook= new AsyncSeriesHook(['name']);
hook.tapAsync('React', (name,cb) =>{
setTimeout(() => {
console.log('React', name);
cb()
},1000)
})
hook.tapAsync('node', (name,cb) => {
setTimeout(() => {
console.log('node', name);
cb()
},1000)
})
hook.callAsync('fdd',function(){
console.log('end')
})- 使用 promise 注册 tapPromise
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34let { AsyncSeriesHook } = require('tapable');
class Less{
constructor(){
this.hooks={
arch: new AsyncSeriesHook(['name'])
}
}
tap(name, task){
this.hooks.arch.tapPromise('node', (name)=>{
return new Promise((resolve,reject)=>{
setTimeout(() => {
console.log('node', name);
resolve()
},1000)
})
})
this.hooks.arch.tapPromise('React',(name)=>{
return new Promise((resolve,reject)=>{
setTimeout(() => {
console.log('React', name);
resolve()
},1000)
})
})
}
start(){
this.hooks.arch.promise('fdd').then(function(){
console.log('end')
})
}
let l =new Lesson()
l.tap() //注册钩子
l.start() //启动钩子
}- AsyncSeriesHook promise 实现原理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34class AsyncSeriesHook{
constructor(args){
this.tasks=[]
}
tapPromise(name, task){
this.tasks.push(task)
}
promise(...args){
let [ first, ...others]=this.tasks;
return others.reduce((p,n) => {
return p.then(()=>n(...args))
},first(...args))
}
}
let hook= new AsyncSeriesHook(['name'])
hook.tapPromise('React',(name) =>{
return new Promise((resolve,reject)=>{
setTimeout(() => {
console.log('React', name);
resolve()
},1000)
})
})
hook.tapPromise('node',(name) =>{
return new Promise((resolve,reject)=>{
setTimeout(() => {
console.log('node', name);
resolve()
},1000)
})
})
hook.promise('fdd').then(() => {
console.log('end1')
})AsyncSeriesWaterfallHook 异步串行瀑布流钩子
- 使用 tapAsync
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30let { AsyncSeriesWaterfallHook } = require('tapable');
class Less{
constructor(){
this.hooks={
arch: new AsyncSeriesWaterfallHook(['name'])
}
}
tap(name, task){
this.hooks.arch.tapAsync('node', (name, cb)=>{
setTimeout(() => {
console.log('node', name);
cb(null,'result)
},1000)
})
this.hooks.arch.tapAsync('React',(data, cb)=>{
setTimeout(() => {
console.log('React', data);
cb(null)
},1000)
})
}
start(){
this.hooks.arch.callAsync('fdd',function(){
console.log('end')
})
}
let l =new Lesson()
l.tap() //注册钩子
l.start() //启动钩子
}- 实现原理 tapAsync
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44class AsyncSeriesWaterfallHook{
constructor(args){
this.tasks=[]
}
tapAsync(name, task){
this.tasks.push(task)
}
callAsync(...args){
let index =0;
let finalCallback = args.pop();
let next = (err, data)=>{
let task = this.tasks[index];
if(!task) return finalCallback();
if(index===0){
task(...args,next)
}else{
if(err === null){
task(data,next);
}else{
finalCallback();
}
}
index++
}
next()
}
}
let hook= new AsyncSeriesWaterfallHook(['name'])
hook.tapAsync('React',(name, cb) =>{
setTimeout(() => {
console.log('React', name);
cb('1',111)
},1000)
})
hook.tapAsync('node',(data, cb) =>{
setTimeout(() => {
console.log('node', data);
cb()
},1000)
})
hook.callAsync('fdd',() => {
console.log('end1')
})使用 promise
1 | let { AsyncSeriesWaterfallHook } = require('tapable'); |
- 实现原理 promise
1 | class AsyncSeriesWaterfallHook{ |
