Open musicode opened 9 years ago
目录结构:
- composer.json - Dispatcher.php - EventServiceProvider.php
在 EventServiceProvider 的 register() 中,往 IoC 容器注册了一个 Dispatcher 对象,键名为 events。
register()
既然是事件模块,不外乎事件绑定、解绑、触发等逻辑,下面我们来分析 Dispatcher。
我们不妨先把 Dispatcher 的功能列举一下:
监听事件的相关数据会存入 $listeners 数组,它的结构如下:
[ 'event name' => [ 'priority' => [ handler1, handler2, ... ] ] ]
可见事件存储分两个维度:priority 和 handler。
listen($event, $handler, 1)
事件的优先级体现在触发事件时 handler 的执行顺序,如果按照 $listeners 的数据结构,我们需要做以下事情:
每次触发事件都要做这三步有些浪费性能,所以 Laravel 新增了一个 $sorted 属性,用来存放这三步的执行结果。
$sorted
来看下 sortListeners()
sortListeners()
protected function sortListeners($eventName) { $this->sorted[$eventName] = array(); if (isset($this->listeners[$eventName])) { krsort($this->listeners[$eventName]); $this->sorted[$eventName] = call_user_func_array('array_merge', $this->listeners[$eventName]); } }
除了完成前面提到的三步,还把二维数组转成了一维,优先级高的 handler 排在前面,这样便降低了遍历的成本。
如果监听事件名包含 *,便认为是通配符监听。
*
通配符监听没有优先级的概念,而且它的 handler 是最后执行的。
举个例子,假设监听了两个事件 show 和 show*,当触发 show 事件时,会先执行 show 的 handler,再执行 show* 的 handler。
show
show*
举个例子,我们给 show 事件注册了一堆 handler,然后我们想触发 show 事件,并给所有 handler 加上一些执行参数,则可以按以下方式调用:
$dispatcher->fire('show', [ 'name' => 'xxx' ]);
这是在触发事件的时候传参,我们也可以在绑定的时候传参,调用方式如下:
$dispatcher->queue('show', [ 'name' => 'xxx' ]); $dispatcher->flush('show');
这套机制,我始终不懂为何要叫 “事件队列”,但是我也没有更好的名字,暂且就这么用吧...
更多内容,请参考 Laravel 文档
目录结构:
在 EventServiceProvider 的
register()
中,往 IoC 容器注册了一个 Dispatcher 对象,键名为 events。既然是事件模块,不外乎事件绑定、解绑、触发等逻辑,下面我们来分析 Dispatcher。
我们不妨先把 Dispatcher 的功能列举一下:
事件优先级
监听事件的相关数据会存入 $listeners 数组,它的结构如下:
可见事件存储分两个维度:priority 和 handler。
listen($event, $handler, 1)
表示优先级是 1,数字越大,表示 handler 越早执行。事件的优先级体现在触发事件时 handler 的执行顺序,如果按照 $listeners 的数据结构,我们需要做以下事情:
每次触发事件都要做这三步有些浪费性能,所以 Laravel 新增了一个
$sorted
属性,用来存放这三步的执行结果。来看下
sortListeners()
除了完成前面提到的三步,还把二维数组转成了一维,优先级高的 handler 排在前面,这样便降低了遍历的成本。
通配符监听
如果监听事件名包含
*
,便认为是通配符监听。通配符监听没有优先级的概念,而且它的 handler 是最后执行的。
举个例子,假设监听了两个事件
show
和show*
,当触发show
事件时,会先执行show
的 handler,再执行show*
的 handler。事件队列
举个例子,我们给 show 事件注册了一堆 handler,然后我们想触发 show 事件,并给所有 handler 加上一些执行参数,则可以按以下方式调用:
这是在触发事件的时候传参,我们也可以在绑定的时候传参,调用方式如下:
这套机制,我始终不懂为何要叫 “事件队列”,但是我也没有更好的名字,暂且就这么用吧...
更多
更多内容,请参考 Laravel 文档