V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
353943780
V2EX  ›  分享创造

链式事件流轻量级迷你 JS 库 - hubJS

  •  
  •   353943780 · 2017-11-03 17:20:17 +08:00 · 2992 次点击
    这是一个创建于 2578 天前的主题,其中的信息可能已经有所发展或是发生改变。

    使用情景

    相信大家都听说过 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 原生事件

     // 绑定 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。

    4 条回复    2017-11-07 15:19:25 +08:00
    353943780
        1
    353943780  
    OP
       2017-11-04 06:49:03 +08:00
    更新了一些使用场景,可以在这里看到哈 https://zhuanlan.zhihu.com/p/30712401
    feichao
        2
    feichao  
       2017-11-04 14:20:11 +08:00
    Rx.js 确实内容比较多, 楼主有看过 xstream ( http://staltz.github.io/xstream/)或是 Most ( https://github.com/cujojs/most)
    这两个也各有特点, 你实现 hubjs 的时候也可以参考下
    353943780
        3
    353943780  
    OP
       2017-11-05 17:47:57 +08:00
    @feichao 谢谢提醒的,其实两个都有看过,而实际项目上就用过 xstream
    ooTwToo
        4
    ooTwToo  
       2017-11-07 15:19:25 +08:00
    哈哈哈哈哈很滑稽啊
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1661 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 16:36 · PVG 00:36 · LAX 08:36 · JFK 11:36
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.