shrikeh / bounce
下一代事件总线,支持多事件和模糊事件匹配
dev-master
2017-07-14 20:14 UTC
Requires
- eventbus-interop/eventbus-interop: ^0.1
- psr/container: ^1.0@dev
- psr/log: ^1.0@dev
Requires (Dev)
- acclimate/container: dev-master
- escapestudios/symfony2-coding-standard: ^2.9
- phpspec/phpspec: ^3.4
- pimple/pimple: ^3.1@dev
- squizlabs/php_codesniffer: ^2.7
This package is auto-updated.
Last update: 2024-09-06 03:31:34 UTC
README
一个允许发射多个事件,并且监听器可以监听多个事件的的事件总线。
概述
许多事件总线存在一个问题,即它们在一个周期内只允许发生一个事件,且事件不会被排队。
这意味着在周期中生成的事件将立即发生,即使这不合适。
Bounce 采用不同的方法,其中监听器可以通过名称或类型模糊匹配事件,并且可以在不中断当前事件周期的情况下触发和排队进一步的事件。在底层,它使用 SPLPriorityQueue、SPLQueue 和 SPLObjectStorage 来高效地在周期中存储和维护监听器和事件。
特性
Bounce 与标准实现相比有几项关键变更
事件匹配
Bounce 有事件 映射 的概念,其中映射表示它是否与特定事件匹配。目前包含两种实现:基于通配符和基于事件类型。这允许对事件进行复杂的匹配
<?php # examples/maps.php use EventIO\InterOp\EventInterface; use Shrikeh\Bounce\Emitter; use Shrikeh\Bounce\Event\Map\EventType; use Shrikeh\Bounce\Event\Map\Glob; use Shrikeh\Bounce\Examples\Mock\Event\Bar; require_once __DIR__.'/../vendor/autoload.php'; $emitter = Emitter::create(); $firstListener = function(EventInterface $event) { echo sprintf("firstListener: %s\n", $event->name()); }; $secondListener = function(Bar $event) { echo sprintf("secondListener: %s\n", $event->name()); }; $firstMap = new Glob('foo.*'); $secondMap = new EventType(Bar::class); $emitter->addListener($firstMap, $firstListener); $emitter->addListener($secondMap, $secondListener); $event = new Bar('foo.bar'); $emitter->emitEvent($event);
上述事件将输出
firstListener: foo.bar secondListener: foo.bar
事件排队
Bounce 允许多个事件被发射。事件以先进先出(FIFO)的顺序排队,并按顺序分发。
<?php # examples/event-queues.php use Shrikeh\Bounce\Emitter; use EventIO\InterOp\EventInterface; require_once __DIR__.'/../vendor/autoload.php'; $listener = function(EventInterface $event) { echo sprintf("event: %s\n", $event->name()); }; $emitter = Emitter::create(); $emitter->addListener('foo.*', $listener); $emitter->emit('foo.bar', 'foo.baz', 'foo.foo');
上述将输出
event: foo.bar event: foo.baz event: foo.foo
PSR-11 容器化监听器
某些监听器可能创建起来很复杂(需要数据库访问、文件处理等)——如果监听器实际上从未被调用,则这些都不必要。相反,Bounce 使用 Psr11Container
,允许监听器按需创建,并且仅在监听器被触发时。以下是一个使用令人惊叹的 Pimple DI 容器以及 Acclimate 适配器的示例
<?php use Acclimate\Container\ContainerAcclimator; use Pimple\Container; use Shrikeh\Bounce\Emitter; use Shrikeh\Bounce\Listener\Psr11Container; require_once __DIR__.'/../vendor/autoload.php'; $pimple = new Container(); $pimple['some_heavy_listener'] = function() { return function() { echo 'has this run?'; }; }; $acclimator = new ContainerAcclimator(); $container = $acclimator->acclimate($pimple); $lazyListener = new Psr11Container($container, 'some_heavy_listener'); $emitter = Emitter::create(); $emitter->addListener('foo.*', $lazyListener); $emitter->emit('foo.bar');
上述将输出 has this run?
。
要求
Bounce 需要 PHP 7.1 或更高版本。
安装
Bounce 使用 composer 安装
composer require shrikeh/bounce
基本用法
<?php # examples/basic-usage.php require_once __DIR__.'/../vendor/autoload.php'; use Shrikeh\Bounce\Emitter; $emitter = Emitter::create(); $firstListener = function($event) { echo sprintf("firstListener: %s\n", $event->name()); }; $secondListener = function($event) { echo sprintf("secondListener: %s\n", $event->name()); }; $emitter->addListener('event.*', $firstListener); $emitter->addListener('*.first', $secondListener); $emitter->emit('event.first', 'event.second', 'event.third');
上述示例将输出
firstListener: event.first secondListener: event.first firstListener: event.second firstListener: event.third