Event::defer() відкладає всі події, що виникли в замиканні, до його завершення.
Event::defer(function () {
$user = User::create(['name' => 'Victoria']);
$user->posts()->create(['title' => 'Перший допис']);
});
Без defer слухач created користувача спрацює одразу після User::create() - ще до створення поста. Якщо слухач розраховує на пов'язані записи (надіслати вітання з посиланням на перший допис), він їх не знайде.
Особливості:
- якщо в замиканні виняток, відкладені події не диспетчеризуються зовсім;
- другим аргументом можна відкласти лише певні події:
['eloquent.created: '.User::class].
Чим відрізняється від after-commit:
Event::defer() |
ShouldDispatchAfterCommit |
|
|---|---|---|
| Чекає | кінця замикання | коміту транзакції бази |
| Транзакція потрібна | ні | так (без неї - одразу) |
| Мета | цілісність набору записів у коді | щоб слухачі не бачили незакомічених даних |
Їх можна поєднувати: defer усередині DB::transaction() збирає події, а after-commit гарантує, що слухачі в черзі побачать закомічені дані.