subscribers.js - 小巧且实用的 JavaScript 发布/订阅工具库。
编写 subscribers.js 主要是在日常的开发中经常需要使用到发布/订阅模式,同时也为初学 JavaScript 的朋友了解 JavaScript中的发布订阅模式实现与应用 所以自己也整理了一个。虽然简单,但基本的功能都有了,还是挺好用的。这个项目的 API 文档就使用到了 subscribers.js。
- 原生 JavaScript 编写,无任何依赖;
- 基于 topic 主题的消息,且支持命名空间的订阅/发布;
- 支持异/同步 发布消息;
- 支持 UMD 规范,同时也提供 ES6 模块调用;
- API 接口易于理解和调用简单;
![]() IE / Edge |
![]() Firefox |
![]() Chrome |
![]() Safari |
![]() Opera |
---|---|---|---|---|
IE11, Edge | last 10 versions | last 10 versions | last 10 versions | last 10 versions |
subscribers.js 支持 UMD 规范和 ES6 的模块调用方式,可以在 Node.js 环境中(仅适用于单线程的 Node.js 应用)使用 npm 安装,也可以在浏览器中使用 script 标签引入到页面。
# install from npmjs.com
npm i -S @yaohaixiao/subscribers.js
在浏览器中调用 subscribers.js,可以选择调用 jsdelivr 提供的 CDN 服务中的文件,也可以使用本地的 subscribers.js 文件。
<script src="https://cdn.jsdelivr.net/gh/yaohaixiao/subscribers.js/subscribers.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/yaohaixiao/subscribers.js/subscribers.core.min.js"></script>
<script src="/path/to/subscribers.min.js"></script>
<script src="/path/to/subscribers.core.min.js"></script>
const subscribers = require('@yaohaixiao/subscribers.js')
// 调用完整功能的 subscribers 对象
import subscribers from '@yaohaixiao/subscribers.js/subscribers'
// 调用 Core 版本的 subscribers 对象,仅包含以下方法:
// on()
// emit()
// off()
import subscribers from '@yaohaixiao/subscribers.js/core'
import subscribers from '@yaohaixiao/subscribers.js/subscribers'
const Person = {
name: 'robert',
age: 24
}
// 创建订阅主题的函数
const handler = (msg, data) => {
console.log( msg, data )
}
/* ==== 订阅主题 ==== */
// 将函数添加到特定主题的订阅者列表中
subscribers.on('log', handler)
// 设置 handler 的执行上下文为 Person
subscribers.on('log', handler, Person)
// 采用命名空间式的消息主题
subscribers.on('log.info', handler)
subscribers.on('log.info.update', handler)
/* ==== 发布主题 ==== */
// 发布一个(名为:log)消息,log 会触发
subscribers.emit('log', 'hello world!')
// log/log.info/log.info.update 主题的处理器函数都将执行
subscribers.emit('log.info.update', `hello world! it's update!`)
/* ==== 取消订阅 ==== */
// 将 handler 函数从 log 主题中订阅者列表中移除
subscribers.off('log', handler)
const token = Subscribers.on('alert', handler)
// 将 handler 函数从 alert 主题中订阅者列表中移除
subscribers.off('alert', token)
// 移除 log 主题及订阅者列表
subscribers.off('log')
subscribers.js 中封装了一系列常用方法,并且适用起来非常方便。
订阅主题,并给出处理器函数。
Category: Core
Type: String
Default: ``
(必须)主题名称。
Type: Function
Default: ``
(必须)主题的处理器函数。
Type: String
唯一的 token 字符串,例如:'guid-1'。
import subscribers from '@yaohaixiao/subscribers.js/subscribers'
const handler = () => {
console.log('author is Robert')
}
const Person = {
name: 'robert',
age: 24
}
subscribers.on('author', handler)
// 设置 handler 的执行上下文为 Person
subscribers.on('log', handler, Person)
// 支持命名空间形式的主题的订阅
subscribers.on('author.career', handler)
subscribers.on('author.career.years', handler)
// 发布消息
subscribers.emit('author', 'Yaohaixiao') // -> `Author: Yaohaixiao`
subscribers.emit('author.career', 'Programmer') // -> `Author: Programmer`
subscribers.emit('author.career.years', 23) // -> `Author: 23`
once() 方法用于订阅主题,并给出处理器函数,仅执行一次。
Type: String
Default: ``
(必须)主题名称。
Type: Function
Default: ``
(必须)主题的处理器函数。
Type: String
唯一的 token 字符串,例如:'guid-1'。
import subscribers from '@yaohaixiao/subscribers.js/subscribers'
const handler = () => {
console.log('author is Robert')
}
subscribers.once('author', handler)
// 发布消息
subscribers.emit('author')
// 再次发布 handler 将不再执行
subscribers.emit('author')
all() 方法用于订阅所有主题消息发布,任何消息发布都会执行 handler() 处理器。
Type: Function
Default: ``
(必须)处理器函数。
Type: String
唯一的 token 字符串,例如:'guid-1'。
import subscribers from '@yaohaixiao/subscribers.js/subscribers'
const handler = (msg) => {
console.log(`handler:${msg}`)
}
const callback = (msg) => {
console.log(`handler:${msg}`)
}
subscribers.on('author', handler)
subscribers.on('career', handler)
// 监听所有消息
subscribers.all(callback)
// 发布消息
subscribers.emit('author', 'Robert')
// -> 'handler:Robert'
// 每次都会触发 all() 方法的订阅处理方法
// -> 'callback:Robert'
subscribers.emit('career', 'Programmer')
// -> 'handler:Programmer'
// -> 'callback:Programmer'
emit() 用于发布订阅主题信息。
subscribers.js 参考了(PubSubJS)默认是采用异步方式发布的。以确保在消费者处理主题时,主题的发起者不会被阻止。 当然 emit() 方法也支持同步方式(浏览器环境下比较适合)发布主题。
Category: Core
Type: String
Default: ``
(必须)主题名称。
Type: Object
Default: ``
(必须)消息传递的数据对象。
Type: Boolean
Default: true
(可选) 是否异步发布。默认值:true。
- 当 async 设置为 true(默认) 时,异步发布;
- 当 async 设置为 false 时,同步发布;
Type: subscribers
subscribers 对象,以便实现链式调用。
import subscribers from '@yaohaixiao/subscribers.js/subscribers'
const handler = (msg) => {
console.log(msg)
}
subscribers.on('author', handler)
subscribers.on('career', handler)
subscribers.on('years', handler)
// 异步发布
subscribers.emit('author', 'ok') // -> 'ok'
// 同步发布
// 延迟10毫秒:应该看输出 ok 后输出 programmer
subscribers.emit('career', 'programmer', false) // -> 'programmer'
notify() 用于同步发布订阅主题信息,是 emit() 方法的别名。
Type: String
Default: ``
(必须)主题名称。
Type: Object
Default: ``
必须)消息传递的数据对象。
Type: subscribers
subscribers 对象,以便实现链式调用。
import subscribers from '@yaohaixiao/subscribers.js/subscribers'
const handler = (msg) => {
console.log(msg)
}
subscribers.on('author', handler)
subscribers.on('career', handler)
subscribers.on('years', handler)
// 依次输出:'author'、'career'、'years'
subscribers.notify('author', 'ok') // -> 'ok'
subscribers.notify('career', 'programmer') // -> 'programmer'
subscribers.notify('years', 19) // -> 19
off() 方法用来取消订阅主题。
Category: Core
Type: String
Default: ``
(必须)主题名称。
Type: Function|String
Default: ``
(可选)订阅主题的处理器函数或者唯一 Id 值。
Type: subscribers
subscribers 对象,以便实现链式调用。
import subscribers from '@yaohaixiao/subscribers.js/subscribers'
const handler = (msg) => {
console.log('handler:', msg)
}
const callback = (msg) => {
console.log('callback:', msg)
}
subscribers.on('author', handler)
const token = subscribers.on('career', handler)
const guid = subscribers.on('career', handler)
// 取消订阅 author 主题
subscribers.off('author', handler)
// 删除订阅 career 主题下的 handler 处理器
subscribers.off('career', token)
// 删除订阅 career 主题下的 callback 处理器
subscribers.off('career', guid)
// 订阅 career 主题下2个处理器都删除后
// 会取消整个 author 主题订阅,因此再发布 author 主题消息
// 不会有任何反应
subscribers.emit('career', 'web developer')
get() 方法用来获取全部或者包含 topic 主题或者订阅 token 的订阅者信息。
Type: String
Default: ``
(可选)主题名称。
- 不传递 topic 参数,返回全部订阅者信息;
- 传递 topic 参数
- 如果是 topic 主题:返回包含 topic 主题的订阅者信息;
- 如果是订阅 token:返回包含此 token 信息的 topic 主题的订阅者信息;
Type: Array | Object
返回全部或者包含 topic 主题或者订阅 token 的订阅者信息。
import subscribers from '@yaohaixiao/subscribers.js/subscribers'
const handler = (msg) => {
console.log('handler:', msg)
}
subscribers.on('author', handler)
subscribers.on('career', handler)
subscribers.on('years', handler)
const token = subscribers.on('years', handler)
// 获取 author 主题订阅者信息
subscribers.get('author')
// -> 返回 author 主题的订阅信息
// [
// topic: 'author',
// callback: handler,
// token: 'guid-1'
// ]
subscribers.get(token)
// -> 返回 career 主题的订阅信息
// [
// topic: 'career',
// callback: handler,
// token: 'guid-2'
// ]
// 获取所有订阅者信息
subscribers.get()
// -> 返回所有主题的订阅信息
// {
// 'author': [
// topic: 'author',
// callback: handler,
// token: 'guid-1'
// ]
// 'career': [
// topic: 'career',
// callback: handler,
// token: 'guid-2'
// ]
// 'years': [
// topic: 'years',
// callback: handler,
// token: 'guid-3'
// ]
// }
has() 方法用于判断是否存在包含 topic 指定的订阅者信息。
Type: String
Default: ``
(可选)主题名称。
- 传递 topic 参数:判断指定 topic 或者消息主题的命名空间中包含 topic 的订阅信息;
- 不传递 topic 参数:判断是否包含任何订阅信息;
Type: Boolean
Default: true
(可选)是否完全匹配 topic。
- true:匹配完全相同的主题或者主题的命名空间中包含 topic 的订阅;
- false:只匹配与指定 topic 主题完全相同的主题;
Type: Boolean
- true:有相关的订阅信息;
- false:无相关的订阅信息;
import subscribers from '@yaohaixiao/subscribers.js/subscribers'
const handler = (msg) => {
console.log('handler:', msg)
}
subscribers.on('author', handler)
subscribers.on('author.career.years', handler)
subscribers.has('author.career')
// => true - 因为包含 author 主题
subscribers.has('author.career.year')
// => true 因为有完全匹配的主题
subscribers.has('author.career', false)
// => false 因为没有完全匹配的主题
subscribers.has()
// => true
remove() 方法用来删除特定 topic 主题的订阅者信息。
Type: String|Array
Default: ``
(必须)主题名称。
- String 类型:删除单个 topic 订阅信息;
- Array 类型:删除多个 topic 订阅信息;
Type: subscribers
subscribers 对象,以便实现链式调用。
import subscribers from '@yaohaixiao/subscribers.js/subscribers'
const handler = (msg) => {
console.log('handler:', msg)
}
const callback = (msg) => {
console.log('callback:', msg)
}
subscribers.on('author', handler)
subscribers.on('publish', callback)
// 删除 author 主题相关的所有信息
subscribers.remove('author')
// 同时删除 author 和 publish 主题相关的所有信息
subscribers.remove(['author', 'publish'])
clear() 方法用于清理所有订阅者(主题和处理器的)信息。
Type: subscribers
subscribers 对象,以便实现链式调用。
import subscribers from '@yaohaixiao/subscribers.js/subscribers'
const handler = (msg) => {
console.log('handler:', msg)
}
subscribers.on('author', handler)
subscribers.on('author.career', handler)
subscribers.on('author.career.years', handler)
// 清理所有订阅者(主题和处理器的)信息
subscribers.clear()
subscribers.has() // -> false
Licensed under MIT License.