相信大家都听说过 RxJS,它无疑是优秀响应式编程库,让在很多事件驱动的 “流” 中随心所欲地为所欲为。
但实际到最近几次项目开发中,暴露了一些开发以外的问题。
首先想到就是对团队开发者的学习路线比较陡峭,特别是对一些前端新人,上手较为难,无法即拿即用。
另外就是功能真的太强大了,如果整个使用的话,带来冗余颇大,如果个别功能自行引入使用的话,也就意味着开发者需要熟悉其 API 封装。
而一些中小型项目,例如就像 Vue 非父子组件通讯,除了使用 “ BUS ” 概念之外,响应式编程的介入也是个不错的选择,但需要一个简单而轻便的库去支持。
于是封装了一个简单上手 事件流驱动的迷你 JS 库 - hubJS。
开源 Github 地址是 github/yyued/hub.js。
未进行 gzip 体积仅仅 6k,在实际几个项目上使用得到了不错的效果 :)
可以通过 npm 进行安装
npm i hub-js --save
或者 直接 下载 min 版本,然后外链使用
<script src="./dist/hub.min.js"></script>
import $hub from 'hub-js';
// 注册监听 “ test ” 的监听器
$hub.listen('test', ( data ) => {
console.log( 'test', data );
});
setInterval(( ) => {
// 主动发送 “ test ” 事件
$hub.emit('test', { code: 1 });
}, 1000);
// 绑定 DOM 事件流 ( 可绑定多个 )
const dispatcher = $hub.DOM('button')
.from('click').emit('dom-click-event')
.from('mousedown').emit('dom-mousedown-event-1').emit('dom-mousedown-event-2');
// 监听 DOM 事件流
$hub.listen('dom-click-event', ( e ) => {
console.log( 'button click', e );
})
$hub.listen('dom-mousedown-event-1', ( e ) => {
console.log( 'button mousedown 1', e );
})
$hub.listen('dom-mousedown-event-2', ( e ) => {
console.log( 'button mousedown 2', e );
})
setTimeout(function() {
// 移除 DOM 监听事件,停止 发送事件流
dispatcher.remove();
}, 10000);
// 设置 store 值
$hub.store.code = 1;
// 监听 store 里具体 某个数值
// 若 这个数值已存在 “当前值”,则监听成功后,立即返回 “当前值”,就像 Rx.BehaviorSubject
$hub.listen('@store/code', ( code ) => {
console.log( 'store code', code );
})
setInterval(() => {
// $hub.emit('@store/code', 1);
++$hub.store.code;
}, 1000);
// 注册转换器
$hub.converter.DOMEventFormat1 = function ( e ) {
return [ e.type, e.target ];
}
$hub.converter.DOMEventFormat2 = function ( e ) {
return [ e.target, e.type ];
}
// 可以通过自由组合 链式 衔接的顺序,进行对流的控制,从而达到你想要的效果
const dispatcher = $hub.DOM('button')
.from('click').convert('DOMEventFormat1').emit('dom-click-event')
.from('mousedown').convert('DOMEventFormat1').emit('dom-mousedown-event');
// 例如 还可以
// $hub.DOM('button').from('click').convert('DOMEventFormat1').emit('dom-click-event1').emit('dom-click-event2')
// $hub.DOM('button').from('click').convert('DOMEventFormat1').convert('DOMEventFormat2').emit('dom-click-event1')
// 监听 DOM 事件流
$hub.listen('dom-click-event', ( e ) => {
console.log( 'button click', e );
})
$hub.listen('dom-mousedown-event', ( e ) => {
console.log( 'button mousedown', e );
})
// 注册一个链式通道
$hub.chain('test').pipe(
// 支持 Promise 阻塞
( d ) => new Promise( ( resolve ) => setTimeout( () => resolve( d + 1 ), 2000 ) ),
( d ) => d + 2,
( d ) => d + 3,
).pipe(
( d ) => d + 3,
);
// 监听链式通道回调
$hub.listen('@chain/test', ( d ) => {
console.log( d );
})
// 触发
$hub.emit( '@chain/test', 1 ); // 10
除了上述几种使用方式之外,hubJS 还支持 Fetch / WebSocket / socket.io 等多种事件源,欢迎大家使用并提出 issues。
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.