zoukankan      html  css  js  c++  java
  • JavaScript的订阅者模式--实现一个简单的事件监听框架

    为什么要用到事件监听?

    在实际开发过程中,经常会遇到下面这种情况:

    某个页面包含Header头部、Nav导航、用户个人信息等。这些模块都要等用户登录之后通过发起Ajax异步请求来获取数据。

    如果按照之前的做法,需要我们在Login成功之后的回调函数中调用各个模块获取数据的函数。这样看貌似没有什么问题,但只要页面的模块发生了改变,我们就需要在Login.success()中进行修改。举一个简单的例子:

    原来的模块是这个样子的:

    用户登录成功后调用各模块的getData()分别发出异步请求来获取数据。

    现在Profile模块被删除,添加一个List模块,那我们就不得不在Login的回调函数中也进行相应的修改。这样各模块就与Login直接发生了强耦合:

    再比如,在做类似百度贴吧发帖这样功能的页面时:在用户提交发帖的表单后,需要刷新帖子的列表。这个时候就要调用列表模块的refresh函数。这个时候如果提交表单的函数没有提供提交成功的回调函数的话,我们就无法判断用户什么时候提交了表单。

    针对这个问题,就出现了事件监听这一解决方案。使用事件监听机制后,我们只需要在Login的回调函数中发布一个事件。相应的,我们只需要在模块初始化时让模块订阅相应的事件即可。在事件触发后,就会调用模块提供的函数。

    这个其实就是JavaScript中的发布-订阅模式,又叫做观察者模式。利用这一模式我们就可以来实现一个简单的事件监听框架。

    代码实现:

    核心代码

    __Core对象为框架的核心代码。其中__List数组用于存储事件名和对应的函数。

    subscribe函数:

    函数接收两个参数,事件名,事件触发后的函数。subscribe函数负责将提供的函数存放到对应的事件数组中。

    publish函数:

    考虑到某个模块可能会触发多个事件,这里通过使Array.prototype.slice.call(arguments)来收集参数,即发布的事件名。通过遍历事件名对应的函数数组并执行对应的函数来达到“广播”的效果。

    unsubscribe函数:

    模块还可以取消订阅。函数接收两个参数,取消订阅的事件名、对应的函数。若不传入函数,则默认清除事件对应的所有函数。

    整体框架:

    出于框架兼容度的考虑,这里的写法参考了JQuery的源码,利用了闭包函数的特性创建了一个安全的作用域。代码刚开始会通过是否存在window对象来判断运行环境是否为浏览器。如果进入if语句,则为非浏览器环境,为factory添加一个true参数。若存在这一参数则不会为全局的window对象添加Events对象。

    代码总览:

    原生Demo:

    效果浏览:

    点击前:

    点击后:

    参考资料:

    javascript中的发布者与订阅者_duanshilong的博客-CSDN博客_发布者订阅者​blog.csdn.net图标

    源代码:

    syk2018/Events-listener​github.com图标
    转载自:https://zhuanlan.zhihu.com/p/161717814
  • 相关阅读:
    STL源码剖析之_allocate函数
    PAT 1018. Public Bike Management
    PAT 1016. Phone Bills
    PAT 1012. The Best Rank
    PAT 1014. Waiting in Line
    PAT 1026. Table Tennis
    PAT 1017. Queueing at Bank
    STL源码剖析之list的sort函数实现
    吃到鸡蛋好吃,看看是哪只母鸡下的蛋:好用的Sqlite3
    cJSON
  • 原文地址:https://www.cnblogs.com/xred/p/14272720.html
Copyright © 2011-2022 走看看