背景
在tapable模块中存储了大量的订阅模式,以下是各个订阅模式的简介。
一、syncHook
syncHook属于同步串行钩子,先订阅先执行,不在意是否有返回值。
使用方法
const { SyncHook } = require('tapable');
class Lesson {
constructor() {
this.hooks = {
// 创建一个发布者对象
vue: new SyncHook(["des"]),
}
}
tap(){
// 订阅消息
this.hooks.vue.tap("zs", function (des) {
console.log("zs", des);
});
this.hooks.vue.tap("ls", function (des) {
console.log("ls", des);
});
}
call(){
// 发布消息
this.hooks.vue.call("vue课程上线了");
}
}
let ls = new Lesson();
ls.tap();
ls.call();
实现原理
// 定义一个类作为发布者
class SyncHook {
constructor(args){
// 缓存列表
this.tasks = [];
// 定义属性保存将来会给订阅者传递多少个参数
this.args = args;
}
// 用于订阅的方法
tap(tag, task){
this.tasks.push(task);
}
// 用于发布的方法
call(...args){
if(args.length < this.args.length){
return new Error("参数个数不对");
}
args = args.slice(0, this.args.length);
this.tasks.forEach(function (task) {
task(...args);
})
}
}
module.exports = SyncHook;
/*
// 1.创建发布者
let hook = new SyncHook(["name", "price"]);
// 2.订阅者像发布者订阅
hook.tap("zs", function (name, price) {
console.log(name, price);
});
hook.tap("ls", function (name, price) {
console.log(name, price);
});
hook.tap("ww", function (name, price) {
console.log(name, price);
});
// 3.发布者发布消息
hook.call("豪车", 88888, 666);
*/
二、SyncBailHooks
SyncBailHooks属于同步串行钩子,先订阅先执行,会根据前一个订阅的返回值,如果不是undefined就不会向下执行
执行方法
// const { SyncBailHook } = require('tapable');
const SyncBailHook = require('./SyncBailHook.js');
class Lesson {
constructor() {
this.hooks = {
// 创建一个发布者对象
vue: new SyncBailHook(["des"]),
}
}
tap(){
// 订阅消息
this.hooks.vue.tap("zs", function (des) {
console.log("zs", des);
// return "1";
return undefined;
});
this.hooks.vue.tap("ls", function (des) {
console.log("ls", des);
// return "2";
});
this.hooks.vue.tap("ww", function (des) {
console.log("ww", des);
return "3";
});
}
call(){
// 发布消息
this.hooks.vue.call("vue课程上线了");
}
}
let ls = new Lesson();
ls.tap();
ls.call();
实现原理
// 定义一个类作为发布者
class SyncBailHook {
constructor(args){
// 缓存列表
this.tasks = [];
// 定义属性保存将来会给订阅者传递多少个参数
this.args = args;
}
// 用于订阅的方法
tap(tag, task){
this.tasks.push(task);
}
// 用于发布的方法
call(...args){
if(args.length < this.args.length){
return new Error("参数个数不对");
}
args = args.slice(0, this.args.length);
// this.tasks.forEach(function (task) {
// task(...args);
// })
for(let i = 0; i < this.tasks.length; i++){
let task = this.tasks[i];
let result = task(...args);
if(result !== undefined){
break;
}
}
}
}
module.exports = SyncBailHook;
/*
// 1.创建发布者
let hook = new SyncHook(["name", "price"]);
// 2.订阅者像发布者订阅
hook.tap("zs", function (name, price) {
console.log(name, price);
});
hook.tap("ls", function (name, price) {
console.log(name, price);
});
hook.tap("ww", function (name, price) {
console.log(name, price);
});
// 3.发布者发布消息
hook.call("豪车", 88888, 666);
*/