shrikeh/bounce

下一代事件总线,支持多事件和模糊事件匹配

dev-master 2017-07-14 20:14 UTC

This package is auto-updated.

Last update: 2024-09-06 03:31:34 UTC


README

一个允许发射多个事件,并且监听器可以监听多个事件的的事件总线。

概述

许多事件总线存在一个问题,即它们在一个周期内只允许发生一个事件,且事件不会被排队。

这意味着在周期中生成的事件将立即发生,即使这不合适。

Bounce 采用不同的方法,其中监听器可以通过名称或类型模糊匹配事件,并且可以在不中断当前事件周期的情况下触发和排队进一步的事件。在底层,它使用 SPLPriorityQueueSPLQueueSPLObjectStorage 来高效地在周期中存储和维护监听器和事件。

特性

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