frodeborli / gjallarhorn
事件发射器功能,包括 on()、off()、once() 方法,用于订阅事件。
1.0.2
2022-12-03 23:49 UTC
Requires
- frodeborli/skuld: ^1.0
- frodeborli/themis: ^1.1
- psr/log: ^3.0
This package is auto-updated.
Last update: 2024-09-04 03:37:02 UTC
README
订阅和发射事件。支持使用 PHP 8 Fibers 的异步事件和同步事件。
用法
将 EventEmitter
接口和 EventEmitterTrait
用于任何发射事件的类。
事件发射器类
use Gjallarhorn\{
EventEmitter,
EventEmitterTrait
};
/**
* These annotations allow you to provide better type hinting in your IDE. Change the `Event $event` according
* to your requirements. In this case we're using PHP 8.1 enums (see below for more information).
*
* @method void on(MatchEvent $event, Closure ...$listener) Subscribe to an event
* @method void off(MatchEvent $event, Closure ...$listener) Unsubscribe from an event
* @method void once(MatchEvent $event, Closure ...$listener) Subscribe to only the next invocation of this event
*/
class FootballMatch implements EventEmitter {
use EventEmitterTrait;
/**
* This function sends off a synchronous event message. If this
* event is emitted from inside an asynchronous event listener,
* then this event will effectively also be asynchronous.
*/
public function triggerGoalEvent(int $player_number, bool $homeTeam) {
return $this->trigger(MatchEvent::GOAL, $player_number, $homeTeam);
}
/**
* This function emits the event and returns a Promise object which
* can be resolved later by calling `$promise->wait()`.
*/
public function triggerGoalEventAsync(int $player_number, bool $homeTeam) {
return $thsi->triggerAsync(MatchEvent::GOAL, $player_number, $homeTeam);
}
}
订阅和取消订阅事件
向事件源对象添加监听器非常简单
/**
* An event handler
*/
function handle_goal_scores(...$args) {
// handle the event
}
/**
* Subscribing to goal scores
*/
$match->on(SomeType::GOAL_SCORED, handle_goal_scores(...));
/**
* Unsubscribing
*/
$match->off(SomeType::GOAL_SCORED, handle_goal_scores(...));
/**
* Subscribe only to the next goal
*/
$match->once(SomeType::GOAL_SCORED, function(int $id, DateTimeInterface $time) {
// The next event
});
异步事件处理器
事件可以异步触发。在这种情况下,EventEmitterTrait::trigger()
函数将返回一个 Promiselike
对象(即任何具有与 function then($onFulfilled, $onRejected)
兼容签名的对象)。
提示 要处理各种承诺类型,您可以考虑使用
RaceTrack\Promise::promisify()
方法。此方法将返回一个具有所有您需要用于处理异步代码的功能的RaceTrack\Promise
实例。
运行异步事件监听器
<?php
use Gjallarhorn\{
EventEmitter,
EventEmitterTrait
};
enum MyEvent: string {
case GOOD_EVENT = 'GOOD_EVENT';
case BAD_EVENT = 'BAD_EVENT';
}
/**
* @method void on(MyEvent $event, Closure ...$listener) Subscribe to an event
* @method void off(MyEvent $event, Closure ...$listener) Unsubscribe from an event
* @method void once(MyEvent $event, Closure ...$listener) Subscribe only to the next invocation of the event
*/
class SomeClass implements EventEmitter {
use EventEmitterTrait;
public function triggerGoodEvent(): void {
$promise = $this->triggerAsync(MyEvent::GOOD_EVENT, $this);
echo "This happens before all events have been resolved\n";
$results = $promise->await();
}
}
$instance = new SomeClass();
$instance->on(MyEvent::GOOD_EVENT, function(SomeClass $emitter) {
// Sleep for 2 seconds while allowing other code to progress
Fiber::suspend(Promise::sleep(2));
echo "I've slept for 2 seconds\n";
});
$instance->triggerGoodEvent();