Quiet
  • 主页
  • 归档
  • 分类
  • 标签
  • 链接
  • 关于我

bajiu

  • 主页
  • 归档
  • 分类
  • 标签
  • 链接
  • 关于我
Quiet主题
  • 前端工程化

tapable简介

bajiu
前端

2021-05-14 17:24:03

最近项目中有了小伙伴儿用了 tapable 控制事件处理, 以前知道 tapable 还是通过 webpack, webpack 通过 tapable 将实现与流程解耦, 所有具体实现通过插件的形式存在,一个类似于 Node.js 中的 EventEmitter的库

一个最简单的栗子

一个同步钩子 SyncHook

const { SyncHook } = require('tapable');
const hook = new SyncHook(['name']);
hook.tap('hello', (name) => {
    console.log(`hello ${name}`);
});
hook.tap('hello again', (name) => {
    console.log(`hello ${name}, again`);
});

hook.call('world !');
// hello world !
// hello world !, again

我们执行 hook.call('world !') 时会依次执行前面 hook.tap(name, callback) 中的回调函数。通过 SyncHook 创建同步钩子,使用 tap 注册回调,再调用 call 来触发

另外也有很多同步钩子:

  • SyncBailHook: 类似于 SyncHook,执行过程中注册的回调返回非 undefined 时就停止不在执行。
  • SyncWaterfallHook: 接受至少一个参数, 上一个注册的回调返回值会作为下一个注册的回调的参数。
  • SyncLoopHook: 有点类似 SyncBailHook, 但是是在执行过程中回调返回非 undefined 时继续再次执行当前的回调。

一个异步钩子 AsyncParallelHook

AsyncParallelHook 顾名思义是并行执行的异步钩子,当注册的所有异步回调都并行执行完毕之后再执行 callAsync 或者 promise 中的函数。

const { AsyncParallelHook } = require('tapable');
const hook = new AsyncParallelHook(['name']);

console.time('cost');

hook.tapAsync('hello', (name, cb) => {
  setTimeout(() => {
    console.log(`hello ${name}`);
    cb();
  }, 2000);
});
hook.tapPromise('hello again', (name) => {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log(`hello ${name}, again`);
      resolve();
    }, 1000);
  });
});

hook.callAsync('ahonn', () => {
  console.log('done');
  console.timeEnd('cost');
});
// hello ahonn, again
// hello ahonn
// done
// cost: 2008.609ms

// 或者通过 hook.promise() 调用
// hook.promise('ahonn').then(() => {
//  console.log('done');
//  console.timeEnd('cost');
// });

一个异步顺序钩子 AsyncSeriesHook

如果你想要顺序的执行异步函数的话,显然 AsyncParallelHook 是不适合的。所以 tapable 提供了另外一个基础的异步钩子: AsyncSeriesHook

const { AsyncSeriesHook } = require('tapable');
const hook = new AsyncSeriesHook(['name']);

console.time('cost');

hook.tapAsync('hello', (name, cb) => {
  setTimeout(() => {
    console.log(`hello ${name}`);
    cb();
  }, 2000);
});
hook.tapPromise('hello again', (name) => {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log(`hello ${name}, again`);
      resolve();
    }, 1000);
  });
});

hook.callAsync('ahonn', () => {
  console.log('done');
  console.timeEnd('cost');
});
// hello ahonn
// hello ahonn, again
// done
// cost: 3011.162ms

上面的示例代码与 AsyncParallelHook 的示例代码几乎相同,不同的是 hook 是通过 new AsyncSeriesHook() 实例化的

通过 AsyncSeriesHook 就能够顺序的执行注册的回调, 除此之外注册与触发的用法都是相同的

**同样的,异步钩子也有一些带流程控制的钩子: **

  • AsyncParallelBailHook: 执行过程中注册的回调返回非 undefined 时就会直接执行 callAsync 或者 promise 中的函数(由于并行执行的原因,注册的其他回调依然会执行)。
  • AsyncSeriesBailHook: 执行过程中注册的回调返回非 undefined 时就会直接执行 callAsync 或者 promise 中的函数,并且注册的后续回调都不会执行。
  • AsyncSeriesWaterfallHook: 与 SyncWaterfallHook 类似,上一个注册的异步回调执行之后的返回值会传递给下一个注册的回调。

文章还是白piao的香啊: https://segmentfault.com/a/1190000020146256

上一篇

顶点着色器(VSHADER) 和 片段着色器(FSHADER) 需要的数据

下一篇

git 常用命令

©2024 By bajiu.