面试官问发布订阅模式是在问什么?

大家好,我是若川。最近组织了源码共读活动,感兴趣的可以加我微信 ruochuan12 参与,已进行了三个多月,大家一起交流学习,共同进步。

本文来自 @simonezhou 小姐姐投稿的第八期笔记。面试官常问发布订阅、观察者模式,我们日常开发也很常用。文章讲述了 mitt、tiny-emitter、Vue eventBus这三个发布订阅、观察者模式相关的源码。

源码地址

  1. mitt:https://github.com/developit/mitt

  2. tiny-emitter:https://github.com/scottcorgan/tiny-emitter

1. mitt 源码解读

1.1 package.json 项目 build 打包(运用到包暂不深究,保留个印象即可)

执行 npm run build:

// 
"scripts": {
    ...
    "bundle": "microbundle -f es,cjs,umd",
    "build": "npm-run-all --silent clean -p bundle -s docs",
    "clean": "rimraf dist",
    "docs": "documentation readme src/index.ts --section API -q --parse-extension ts",
   ...
 },
  • 使用 npm-run-all(A CLI tool to run multiple npm-scripts in parallel or sequential:https://www.npmjs.com/package/npm-run-all) 命令执行38a43cfbe1353f746aacbc56ca41baa8.png

  • clean 命令,使用 rimraf(The UNIX command rm -rf for node. https://www.npmjs.com/package/rimraf)删除 dist 文件路径

  • bundle 命令,使用 microbundle(The zero-configuration bundler for tiny modules, powered by Rollup. https://www.npmjs.com/package/microbundle) 进行打包

  • microbundle 命令指定 format: es, cjs, umd,  package.json 指定 soucre 字段为打包入口 js:

37e472a5cf49fde482c5b540cdd2ee24.png

{
 "name": "mitt",          // package name
  ...
  ...
  "module": "dist/mitt.mjs",    // ES Modules output bundle
  "main": "dist/mitt.js",      // CommonJS output bundle
  "jsnext:main": "dist/mitt.mjs",   // ES Modules output bundle
  "umd:main": "dist/mitt.umd.js",  // UMD output bundle
  "source": "src/index.ts",     // input
  "typings": "index.d.ts",     // TypeScript typings directory
  "exports": {
    "import": "./dist/mitt.mjs",    // ES Modules output bundle
    "require": "./dist/mitt.js",  // CommonJS output bundle
    "default": "./dist/mitt.mjs"  // Modern ES Modules output bundle
  },
  ...
}

1.2 如何调试查看分析?

使用 microbundle watch 命令,新增 script,执行 npm run dev:

"dev": "microbundle watch -f es,cjs,umd"

对应目录新增入口,比如 test.js,执行 node test.js 测试功能:

const mitt = require('./dist/mitt');

const Emitter = mitt();

Emitter.on('test', (e, t) => console.log(e, t));

Emitter.emit('test', { a: 12321 });

对应源码 src/index.js 也依然可以加相关的 log 进行查看,代码变动后会触发重新打包

1.3. TS 声明

使用上可以(官方给的例子),比如定义 foo 事件,回调函数里面的参数要求是 string 类型,可以想象一下源码 TS 是怎么定义的:

import mitt from 'mitt';

// key 为事件名,key 对应属性为回调函数的参数类型 
type Events = {
  foo: string;
  bar?: number; // 对应事件允许不传参数
};

const emitter = mitt<Events>(); // inferred as Emitter<Events>

emitter.on('foo', (e) => {}); // 'e' has inferred type 'string'

emitter.emit('foo', 42); // Error: Argument of type 'number' is not assignable to parameter of type 'string'. (2345)

emitter.on('*', (type, e) => console.log(type, e) )

源码内关于 TS 定义(关键几句):

export type EventType = string | symbol;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值