读TAPABLE源码后,认识了这几个钩子

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)
})

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值