美文网首页
事件驱动编程

事件驱动编程

作者: 靳晓阳s | 来源:发表于2017-10-29 22:03 被阅读79次

    前言

    从 js 中的事件模型,到 Yii2 中的是事件,再到 nginx 事件机制。我愈发想要搞清楚事件究竟是怎么会事了,现在我们仅从概念上去深入理解事件。

    js 中的事件

    两个小 demo

    HTML 有能力使 HTML 事件触发浏览器中的动作(action),比如当用户点击某个按钮时候,就会触发 按钮点击 事件,js 监听到这个事件之后就可以做出相应的动作了。

    <input type="button" onclick="fun()">
    //通过JS代码指定属性值:
    var btn = document.getElementById('.btn');
    btn.onclick = fun;
    //移除监听函数:
    btn.onclick = null;
    

    这是简单的事件例子,这个事件没什么可说的。

    稍微复杂一点的如一下:

    // 取 btn 对象
    var btn = document.getElementById('.btn');
    // 事件绑定
    btn.addEventListener(‘click’, showMessage, false);
    // 事件移除监听
    btn.removeEventListener(‘click’, showMessage, false);
    

    在该事件模型中有三个过程:1. 事件捕获;2. 事件处理;3. 事件冒泡

    在这个两个案例中,事件是与浏览器或文档交互的瞬间,如点击按钮,填写表格等,它是 js 与 HTML 之间交互的桥梁。值得注意就是一个事件流的概念。

    为什么 js 和 html 之间要引入“事件”这个概念

    在 web前端,以及其它 GUI 编程上,操作视图的只能有一个进程,否则如果两个进程同时修改一个对象那不就要打架了。在一个进程的前提下,要想获取用户的操作要么就是一直轮询,要么就是中断。显然轮询不合理啊,那么引入事件,用户做的操作放入消息循环中,js 进程只需要从循环中取消息不断地取执行操作就可以了。

    PHP框架Yii2 中的事件

    在服务端开发逻辑中,使用事件,可以在特定的时点,触发执行预先设定的一段代码,事件既是代码解耦的一种方式,也是设计业务流程的一种模式。现代软件中,事件无处不在,比如,你发了个微博,触发了一个事件,导致关注你的人,看到了你新发出来的内容。

    其实 Yii2 中的事件就是一个观察者模式,比如说在登陆之后需要做一些列操作,记录日志,通知粉丝该用户已登陆,更新购物车等。那么就可以给日志,更新购物车等绑定登陆成功事件,在登陆成功之后触发登陆成功事件即可。

    class UserController extends Controller {
        //  定义事件名字
        const EVENT_USER_LOGIN = 'user_login';
        
        public function __construct(){
            //  绑定事件
            $this->on(self::EVENT_USER_LOGIN,['app\models\OLog','add']); 
            $this->on(self::EVENT_USER_LOGIN,['app\models\Admin','sendMail']); 
            $this->on(self::EVENT_USER_LOGIN,['app\models\User','updateCart']); 
        }
        
        public function actionIndex(){
            // 这里有一些代码.....
            Yii::$app->user->login($user);
            $this->trigger(self::EVENT_USER_LOGIN);                         
        }
    }
    

    不用事件行不行,可以。只不过代码更不容易维护而已,结构会越来越臃肿。

    Node.js 的异步事件

    Node.js 这门神奇的语言有出场了,基本的事件和上述一致,但 Node.js 是异步的啊,所以就有了异步事件。

    const fs = require('fs');
    const EventEmitter = require('events');
    
    class WithTime extends EventEmitter {
      execute(asyncFunc, ...args) {
        this.emit('begin');
        console.time('execute');
        asyncFunc(...args, (err, data) => {
          if (err) {
            return this.emit('error', err);
          }
    
          this.emit('data', data);
          console.timeEnd('execute');
          this.emit('end');
        });
      }
    }
    
    const withTime = new WithTime();
    
    withTime.on('begin', () => console.log('About to execute'));
    withTime.on('end', () => console.log('Done with execute'));
    
    withTime.execute(fs.readFile, __filename);
    

    疑惑

    其实只是对事件有了一个简单的了解,后续继续深入探索吧。

    --EOF--

    相关文章

      网友评论

          本文标题:事件驱动编程

          本文链接:https://www.haomeiwen.com/subject/yfjupxtx.html