webpack的灵魂tapable学习笔记

tapable 本质上是一种事件流的机制,帮助我们将各个插件串联起来 包含(发布订阅模式)

1.SyncHook用法
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() // 发布
复制代码
自己实现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('cat',function(name){
    console.log('cat', name)
})
hook.tap('dog',function(name){
    console.log('dog', name)
})
hook.call('mam')

// dog mam
// cat mam

复制代码
2.SyncBailHook

串行同步执行,有一个返回值不为undefined就跳过剩下逻辑, bail是保险的意思,表示有一个出错就不往下执行了

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
复制代码
自己实现SyncBailHook

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')
复制代码
3.SyncWaterfallHook

就想水流动一样,下一个任务可以得到上一个任务的返回值

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
复制代码
自己实现SyncWaterfallHook
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
复制代码
  • tapabel中有三种注册方式

tap: 同步注册 tapAsync: 异步注册 tapPromise: 注册时promise

  • 分别对应三种调用方式

call callAsync promise

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值