در یک پروژه کوچک، ممکن است تمام عملیات مربوط به یک درخواست را داخل Controller انجام دهیم. اما با بزرگتر شدن پروژه، این روش بهسرعت باعث ایجاد Controllerهای شلوغ، وابستگیهای زیاد و کدهای سخت برای نگهداری میشود.
فرض کنید در یک فروشگاه اینترنتی، کاربر سفارشی ثبت میکند. بعد از ثبت سفارش ممکن است لازم باشد چند عملیات مختلف انجام شود:
- ارسال Notification برای کاربر
- ارسال ایمیل
- ثبت Log
- بهروزرسانی آمار فروش
- ارسال اطلاعات به یک سرویس خارجی
- ایجاد Job
- بهروزرسانی موجودی
- اطلاعرسانی به مدیر
اگر تمام این عملیات را مستقیماً داخل متدی مانند store() قرار دهیم، کد بهمرور پیچیده میشود.
اینجاست که Event و Listener در Laravel کاربرد پیدا میکنند.
Event به ما میگوید که یک اتفاق مشخص در سیستم رخ داده است و Listener مشخص میکند که در پاسخ به آن اتفاق چه کاری باید انجام شود.
در این مقاله یاد میگیریم:
- Event چیست؟
- Listener چیست؟
- Event و Listener چه تفاوتی دارند؟
- چگونه Event بسازیم؟
- چگونه Listener بسازیم؟
- چگونه Listener را به Event متصل کنیم؟
- چگونه Event را Dispatch کنیم؟
- چگونه چند Listener برای یک Event داشته باشیم؟
- چگونه Listener را وارد Queue کنیم؟
- Event و Notification چه تفاوتی دارند؟
- چه زمانی از Event و Listener استفاده کنیم؟
# Event در Laravel چیست؟
Event یا رویداد، نشاندهنده وقوع یک اتفاق در برنامه است.
برای مثال:
Order Created
User Registered
Payment Completed
Ticket Replied
Password Changed
Order Shipped
هرکدام از این موارد میتوانند یک Event باشند.
برای مثال:
OrderCreated
یعنی:
> یک سفارش جدید ایجاد شده است.
Event خودش لزوماً کاری انجام نمیدهد.
وظیفه Event این است که اطلاعات مربوط به اتفاقی که رخ داده را در اختیار بخشهای دیگری از برنامه قرار دهد.
# Listener در Laravel چیست؟
Listener بخشی از برنامه است که به یک Event واکنش نشان میدهد.
اگر Event بگوید:
OrderCreated
Listener میتواند بگوید:
وقتی سفارش ایجاد شد:
→ ایمیل ارسال کن
یا:
وقتی سفارش ایجاد شد:
→ Notification ایجاد کن
یا:
وقتی سفارش ایجاد شد:
→ اطلاعات را به سرویس خارجی ارسال کن
بنابراین میتوان مفهوم آنها را اینگونه خلاصه کرد:
| مفهوم | وظیفه |
|---|---|
| Event | اعلام وقوع یک اتفاق |
| Listener | واکنش به آن اتفاق |
# یک مثال ساده از Event و Listener
فرض کنید کاربر ثبتنام میکند.
به جای اینکه داخل Controller تمام کارهای مربوط به ثبتنام را انجام دهیم:
public function register()
{
// create user
// send email
// create notification
// log activity
// ...
}
میتوانیم بعد از ایجاد کاربر یک Event ارسال کنیم:
event(new UserRegistered($user));
سپس Listenerهای مختلف به آن واکنش نشان دهند:
UserRegistered
│
├── SendWelcomeEmail
│
├── CreateUserNotification
│
└── LogUserRegistration
در نتیجه Controller فقط مسئول ایجاد کاربر است و بخشهای دیگر مسئولیتهای خودشان را انجام میدهند.
# چرا از Event و Listener استفاده کنیم؟
مهمترین دلیل استفاده از Event و Listener، جدا کردن مسئولیتها است.
فرض کنید در زمان ثبت سفارش باید پنج عملیات انجام شود.
بدون Event ممکن است Controller به چنین چیزی تبدیل شود:
public function store()
{
$order = Order::create(...);
$this->sendEmail($order);
$this->createNotification($order);
$this->updateStatistics($order);
$this->sendToExternalService($order);
$this->createLog($order);
}
با افزایش امکانات، این Controller بسیار شلوغ خواهد شد.
اما با Event:
public function store()
{
$order = Order::create(...);
event(new OrderCreated($order));
}
سپس Listenerها مسئول ادامه کار خواهند بود.
این معماری باعث میشود:
- Controller سادهتر شود.
- مسئولیتها از هم جدا شوند.
- اضافه کردن قابلیت جدید سادهتر شود.
- تست کردن بخشها راحتتر شود.
- وابستگی بین قسمتهای مختلف کمتر شود.
# ساخت Event در Laravel
برای ساخت Event میتوانیم از Artisan استفاده کنیم.
دستور زیر را اجرا کنید:
php artisan make:event OrderCreated
Laravel فایل Event را ایجاد میکند.
معمولاً فایل در مسیر زیر قرار میگیرد:
app/Events/OrderCreated.php
ساختار اولیه Event تقریباً به شکل زیر است:
<?php
namespace App\Events;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class OrderCreated
{
use Dispatchable, SerializesModels;
public function __construct()
{
//
}
}
# ارسال اطلاعات به Event
معمولاً Event باید اطلاعات مربوط به اتفاق را همراه خودش داشته باشد.
مثلاً اگر Event مربوط به ایجاد سفارش است، بهتر است سفارش را به آن ارسال کنیم:
public function __construct(
public Order $order
) {
}
در نتیجه:
<?php
namespace App\Events;
use App\Models\Order;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class OrderCreated
{
use Dispatchable;
use SerializesModels;
public function __construct(
public Order $order
) {
}
}
حالا هر Listener که به این Event متصل باشد، به $order دسترسی خواهد داشت.
# ساخت Listener در Laravel
حالا باید مشخص کنیم وقتی OrderCreated اتفاق افتاد، چه کاری انجام شود.
برای ساخت Listener میتوانیم از Artisan استفاده کنیم:
php artisan make:listener SendOrderCreatedNotification --event=OrderCreated
Laravel فایل Listener را ایجاد میکند.
معمولاً فایل در:
app/Listeners/SendOrderCreatedNotification.php
قرار میگیرد.
ساختار آن تقریباً به شکل زیر است:
<?php
namespace App\Listeners;
use App\Events\OrderCreated;
class SendOrderCreatedNotification
{
public function handle(OrderCreated $event): void
{
//
}
}
مهمترین بخش Listener متد handle() است.
# متد handle در Listener
متد handle() جایی است که عملیات مربوط به Event را انجام میدهیم.
مثلاً:
public function handle(OrderCreated $event): void
{
$order = $event->order;
// do something
}
اگر Event شامل سفارش باشد، Listener از طریق:
$event->order
به آن دسترسی خواهد داشت.
# اتصال Event به Listener
حالا باید به Laravel بگوییم:
> وقتی OrderCreated اجرا شد، SendOrderCreatedNotification را اجرا کن.
در نسخههای جدید Laravel میتوان این ارتباط را با Event Discovery یا ثبت صریح Listenerها مدیریت کرد.
یکی از روشهای واضح و قابل فهم، تعریف Event و Listener در Event Service Provider است.
ساختار مورد نظر:
protected $listen = [
OrderCreated::class => [
SendOrderCreatedNotification::class,
],
];
در این ساختار مشخص شده است که:
OrderCreated
↓
SendOrderCreatedNotification
# استفاده از EventServiceProvider
در پروژههایی که Eventها و Listenerهای زیادی دارند، ثبت صریح ارتباط آنها میتواند خوانایی ساختار را بیشتر کند.
مثلاً:
<?php
namespace App\Providers;
use App\Events\OrderCreated;
use App\Listeners\SendOrderCreatedNotification;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
class EventServiceProvider extends ServiceProvider
{
protected $listen = [
OrderCreated::class => [
SendOrderCreatedNotification::class,
],
];
}
نکته مهم این است که محل و روش ثبت Eventها بسته به ساختار نسخه Laravel و تنظیمات پروژه میتواند متفاوت باشد؛ بنابراین بهتر است ساختار موجود در پروژه خود را نیز در نظر بگیرید.
# Event Discovery چیست؟
Laravel میتواند Event و Listenerها را بهصورت خودکار نیز شناسایی کند.
در این روش، Laravel بر اساس ساختار کلاسها و Type Hint موجود در متد handle() میتواند ارتباط Event و Listener را تشخیص دهد.
مثلاً Listener زیر:
class SendOrderCreatedNotification
{
public function handle(OrderCreated $event): void
{
// ...
}
}
به وضوح نشان میدهد که این Listener به OrderCreated مربوط است.
این روش باعث میشود در بعضی پروژهها نیازی به تعریف دستی تمام ارتباطها نباشد.
برای بررسی Eventهای شناساییشده نیز میتوان از Artisan استفاده کرد:
php artisan event:list
این دستور Eventها و Listenerهای مرتبط را نمایش میدهد.
# Dispatch کردن Event
بعد از ایجاد Event و Listener، باید Event را اجرا کنیم.
برای مثال:
event(new OrderCreated($order));
این کار باعث میشود Laravel Event را Dispatch کند.
روش دیگر:
OrderCreated::dispatch($order);
در صورتی که Event از Trait Dispatchable استفاده کند، میتوان از این روش نیز استفاده کرد.
بنابراین میتوانیم بعد از ایجاد سفارش بنویسیم:
$order = Order::create([
'user_id' => auth()->id(),
'total' => 500000,
]);
event(new OrderCreated($order));
Laravel Event را دریافت میکند و Listenerهای مرتبط را اجرا خواهد کرد.
# یک مثال کامل از Event و Listener
فرض کنید کاربر یک سفارش ثبت میکند.
مرحله اول: Event
<?php
namespace App\Events;
use App\Models\Order;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class OrderCreated
{
use Dispatchable;
use SerializesModels;
public function __construct(
public Order $order
) {
}
}
مرحله دوم: Listener
<?php
namespace App\Listeners;
use App\Events\OrderCreated;
class SendOrderCreatedNotification
{
public function handle(OrderCreated $event): void
{
$order = $event->order;
$order->user->notify(
new OrderCreatedNotification($order)
);
}
}
مرحله سوم: اجرای Event
event(new OrderCreated($order));
ساختار نهایی:
Create Order
│
▼
OrderCreated Event
│
▼
SendOrderCreatedNotification
│
▼
Notification
این ساختار باعث میشود منطق ثبت سفارش از منطق اطلاعرسانی جدا شود.
# چند Listener برای یک Event
یکی از مهمترین مزایای Eventها این است که یک Event میتواند چند Listener داشته باشد.
مثلاً:
OrderCreated
│
├── SendOrderNotification
│
├── UpdateSalesStatistics
│
├── SendOrderToExternalService
│
└── LogOrderCreation
در ثبت Event میتوان چند Listener تعریف کرد:
protected $listen = [
OrderCreated::class => [
SendOrderNotification::class,
UpdateSalesStatistics::class,
SendOrderToExternalService::class,
LogOrderCreation::class,
],
];
حالا هر Listener مسئول یک کار مشخص است.
# مزیت چند Listener چیست؟
فرض کنید چند ماه بعد تصمیم بگیرید هنگام ثبت سفارش، یک اطلاعات جدید نیز در سرویس خارجی ثبت شود.
بدون Event ممکن است مجبور شوید Controller اصلی را تغییر دهید.
اما با Event کافی است یک Listener جدید اضافه کنید:
OrderCreated
│
├── SendNotification
├── UpdateStatistics
├── CreateLog
└── SyncExternalService
این یکی از مهمترین دلایل استفاده از Event در پروژههای بزرگ است.
# Event و Notification چه تفاوتی دارند؟
این دو مفهوم بسیار نزدیک به نظر میرسند اما یکسان نیستند.
Event اعلام میکند که یک اتفاق در سیستم رخ داده است.
Notification وظیفه اطلاعرسانی به یک دریافتکننده را بر عهده دارد.
مثلاً:
Order Created
│
▼
Event
│
▼
Listener
│
▼
Notification
در این معماری:
Event = چه اتفاقی افتاد؟
Listener = در پاسخ چه کاری انجام دهیم؟
Notification = چگونه کاربر را مطلع کنیم؟
این تفکیک باعث میشود معماری پروژه تمیزتر شود.
# Event و Job چه تفاوتی دارند؟
Event و Job نیز دو مفهوم متفاوت هستند.
Event
میگوید:
> اتفاقی رخ داده است.
Job
میگوید:
> یک کار مشخص باید انجام شود.
برای مثال:
OrderCreated Event
│
▼
SendOrderEmail Listener
│
▼
SendOrderEmail Job
│
▼
Queue
در پروژههای بزرگ میتوان Event، Listener، Job و Queue را در کنار هم استفاده کرد.
# Queue کردن Listener
گاهی Listener کاری انجام میدهد که زمانبر است.
مثلاً:
- ارسال ایمیل
- ارتباط با API خارجی
- پردازش فایل
- ارسال اطلاعات به سرویس دیگر
- محاسبات سنگین
در این شرایط میتوان Listener را Queue کرد.
کافی است Listener قرارداد ShouldQueue را پیادهسازی کند:
use Illuminate\Contracts\Queue\ShouldQueue;
class SendOrderCreatedNotification implements ShouldQueue
{
public function handle(OrderCreated $event): void
{
// ...
}
}
حالا Laravel میتواند اجرای Listener را به Queue منتقل کند.
ساختار کار:
User
│
▼
Create Order
│
▼
OrderCreated
│
▼
Queue
│
▼
Worker
│
▼
Send Notification
در نتیجه کاربر مجبور نیست تا پایان اجرای عملیات سنگین منتظر بماند.
# چرا Queue کردن Listener مهم است؟
فرض کنید بعد از ثبت سفارش باید با سه API خارجی ارتباط برقرار شود.
اگر همه این عملیات بهصورت مستقیم اجرا شوند:
Request
│
├── API 1
├── API 2
└── API 3
ممکن است Response کاربر چند ثانیه طول بکشد.
اما اگر Listener به Queue منتقل شود:
Request
│
▼
Order Created
│
▼
Response
│
└───────────────► Queue Worker
│
├── API 1
├── API 2
└── API 3
کاربر سریعتر Response دریافت میکند.
موضوع Queue در مقاله جداگانهای از همین کلاستر با جزئیات بیشتر بررسی خواهد شد.
# Listenerهای شرطی
گاهی Listener باید فقط در شرایط خاصی اجرا شود.
برای مثال:
public function handle(OrderCreated $event): void
{
if ($event->order->total < 100000) {
return;
}
// process large order
}
در این حالت Listener فقط برای سفارشهای بالاتر از مقدار مشخص عملیات را انجام میدهد.
البته اگر شرط بخشی از منطق مهم کسبوکار باشد، بهتر است معماری را طوری طراحی کنیم که مسئولیتها بیش از حد داخل Listener متمرکز نشوند.
# ساخت Event برای ثبتنام کاربر
مثال دیگری را بررسی کنیم.
فرض کنید بعد از ثبتنام کاربر باید ایمیل خوشآمدگویی ارسال شود.
Event:
php artisan make:event UserRegistered
Listener:
php artisan make:listener SendWelcomeEmail --event=UserRegistered
Event:
class UserRegistered
{
use Dispatchable;
use SerializesModels;
public function __construct(
public User $user
) {
}
}
Listener:
class SendWelcomeEmail
{
public function handle(UserRegistered $event): void
{
$user = $event->user;
// send welcome email
}
}
و بعد از ثبت کاربر:
event(new UserRegistered($user));
اکنون فرآیند به شکل زیر است:
Register User
│
▼
UserRegistered
│
▼
SendWelcomeEmail
# Eventهای داخلی Laravel
Laravel خودش نیز در بخشهای مختلف از Event استفاده میکند.
برای مثال در بخشهای مختلف Framework ممکن است Eventهایی مربوط به:
- Authentication
- Database
- Queue
- Request
- Broadcasting
وجود داشته باشد.
به همین دلیل آشنایی با Event و Listener فقط برای ساخت قابلیتهای اختصاصی پروژه مفید نیست؛ بلکه برای درک معماری داخلی Laravel نیز اهمیت دارد.
# مشاهده Eventهای پروژه
برای مشاهده Eventها و Listenerهای قابل شناسایی پروژه میتوان از:
php artisan event:list
استفاده کرد.
این دستور هنگام Debug کردن ارتباط Eventها نیز بسیار مفید است.
اگر Listener مورد انتظار شما در لیست وجود ندارد، باید بررسی کنید که:
- کلاس Listener درست تعریف شده باشد.
- Event درست Type Hint شده باشد.
- Listener در محل مورد انتظار قرار گرفته باشد.
- Event Discovery یا ثبت دستی Listener درست تنظیم شده باشد.
# پاک کردن Cache مربوط به Eventها
اگر تغییراتی در ساختار Event و Listener ایجاد کردهاید و Laravel رفتار قدیمی نشان میدهد، ممکن است لازم باشد Cacheهای مربوط به Event بررسی شوند.
در محیطهای مختلف Laravel امکانات مربوط به Cache و Discovery میتوانند روی رفتار برنامه اثر بگذارند.
در صورت نیاز میتوان Cacheهای Framework را با دستورات مناسب محیط پروژه پاک کرد.
همیشه قبل از اجرای دستورات پاکسازی در Production بهتر است تأثیر آنها بر سایر Cacheهای برنامه را در نظر بگیرید.
# Eventها و تراکنشهای Database
یک نکته مهم در پروژههای واقعی این است که Event را در چه زمانی Dispatch میکنیم.
فرض کنید سفارش هنوز داخل یک Database Transaction قرار دارد:
DB::transaction(function () use ($orderData) {
$order = Order::create($orderData);
event(new OrderCreated($order));
});
اگر Listener بلافاصله عملیاتی مانند ارسال اطلاعات به یک سرویس خارجی انجام دهد، باید دقت کنیم که Transaction هنوز Commit نشده باشد.
در پروژههای حساس، زمان اجرای Event و Listener نسبت به Commit شدن Transaction اهمیت زیادی دارد.
Laravel برای برخی سناریوها امکان اجرای Listener بعد از Commit شدن Transaction را نیز فراهم میکند.
این موضوع مخصوصاً در پروژههایی که Queue، Database Transaction و سرویسهای خارجی همزمان استفاده میشوند اهمیت زیادی دارد.
# Event و معماری تمیز پروژه
یکی از مهمترین کاربردهای Event و Listener، کمک به طراحی معماری تمیزتر است.
مثلاً یک پروژه فروشگاهی را تصور کنید:
app/
├── Events/
│ ├── OrderCreated.php
│ ├── OrderPaid.php
│ └── OrderShipped.php
│
├── Listeners/
│ ├── SendOrderNotification.php
│ ├── UpdateSalesStatistics.php
│ ├── SyncOrder.php
│ └── LogOrderActivity.php
│
├── Notifications/
│ ├── OrderCreatedNotification.php
│ └── OrderShippedNotification.php
│
└── Jobs/
├── SyncOrderJob.php
└── SendExternalRequest.php
این ساختار کمک میکند هر بخش مسئولیت مشخصی داشته باشد.
# چه زمانی از Event و Listener استفاده کنیم؟
Event و Listener زمانی بسیار مفید هستند که یک اتفاق بتواند باعث چند عملیات مستقل شود.
مثلاً:
ثبتنام کاربر
UserRegistered
├── SendWelcomeEmail
├── CreateNotification
└── LogRegistration
ثبت سفارش
OrderCreated
├── SendNotification
├── UpdateStatistics
├── LogActivity
└── SyncExternalService
پرداخت موفق
PaymentCompleted
├── SendReceipt
├── UpdateOrder
├── CreateNotification
└── UpdateWallet
در چنین شرایطی Event میتواند وابستگی بین بخشها را کاهش دهد.
# چه زمانی Event لازم نیست؟
استفاده از Event برای همه عملیاتها ضروری نیست.
اگر یک عملیات ساده و مستقیم دارید، ممکن است استفاده از Event فقط پیچیدگی اضافه ایجاد کند.
مثلاً:
$user->update([
'name' => $name,
]);
برای چنین کاری نیازی نیست حتماً Event ایجاد کنیم.
Event زمانی ارزش بیشتری دارد که یک اتفاق بتواند باعث چند واکنش مستقل شود یا بخواهیم بخشهای مختلف سیستم را از یکدیگر جدا کنیم.
# اشتباهات رایج در Event و Listener
۱. استفاده بیش از حد از Event
Event نباید برای هر خط کد ایجاد شود.
اگر هر عملیات ساده یک Event داشته باشد، دنبال کردن جریان اجرای برنامه سخت میشود.
۲. قرار دادن منطق زیاد داخل Event
Event بهتر است بیشتر حامل اطلاعات مربوط به اتفاق باشد.
منطق اصلی معمولاً باید در Listener، Service یا بخش مناسب دیگری قرار بگیرد.
۳. ساخت Listenerهای بسیار بزرگ
Listener نباید تبدیل به یک کلاس چندصد خطی شود.
اگر Listener عملیات زیادی انجام میدهد، بهتر است آن عملیات را به Service یا Jobهای جداگانه تقسیم کنیم.
۴. اجرای عملیات سنگین بدون Queue
اگر Listener عملیات زمانبر انجام میدهد، Queue کردن آن را بررسی کنید.
۵. وابستگی بیش از حد Listenerها به یکدیگر
Listenerها بهتر است تا حد امکان مستقل باشند.
برای مثال بهتر است:
OrderCreated
├── Listener A
├── Listener B
└── Listener C
و Listener B وابسته به این نباشد که Listener A قبلاً اجرا شده است؛ مگر اینکه این وابستگی بخشی از طراحی آگاهانه سیستم باشد.
# تفاوت Event، Listener، Notification و Job
برای جمعبندی این چهار مفهوم:
| مفهوم | سؤال اصلی |
|---|---|
| Event | چه اتفاقی افتاد؟ |
| Listener | در واکنش به این اتفاق چه کنیم؟ |
| Notification | چگونه کاربر یا دریافتکننده را مطلع کنیم؟ |
| Job | چه کاری باید اجرا شود؟ |
| Queue | این کار چه زمانی و به چه شکل غیرهمزمان اجرا شود؟ |
یک معماری واقعی میتواند چنین ساختاری داشته باشد:
Order Created
│
▼
Event
│
├───────────────┐
▼ ▼
Notification Listener
│
▼
Job
│
▼
Queue
این تفکیک مسئولیت یکی از ویژگیهای مهم معماری Laravel است.
# جمعبندی
Event و Listener یکی از ابزارهای مهم Laravel برای جدا کردن بخشهای مختلف یک برنامه هستند.
Event اعلام میکند که یک اتفاق رخ داده است و Listener مشخص میکند که در واکنش به آن اتفاق چه کاری انجام شود.
برای ساخت Event:
php artisan make:event OrderCreated
برای ساخت Listener:
php artisan make:listener SendOrderCreatedNotification --event=OrderCreated
و برای اجرای Event:
event(new OrderCreated($order));
یک Event میتواند چند Listener داشته باشد:
OrderCreated
├── SendNotification
├── UpdateStatistics
├── CreateLog
└── SyncExternalService
همچنین Listenerهایی که عملیات سنگین انجام میدهند میتوانند با ShouldQueue وارد Queue شوند.
به این ترتیب به جای اینکه Controller مسئول تمام عملیات باشد، هر بخش وظیفه مشخص خودش را انجام میدهد.
این معماری مخصوصاً در پروژههای بزرگ مانند:
- فروشگاه اینترنتی
- SaaS
- CMS
- سیستم تیکت
- سیستم پرداخت
- پنل مدیریت
- Marketplace
بسیار کاربردی است.
# سوالات متداول
Event در Laravel چیست؟
Event روشی برای اعلام وقوع یک اتفاق در برنامه است؛ مانند ثبت سفارش، ثبتنام کاربر یا تکمیل پرداخت.
Listener در Laravel چیست؟
Listener کلاسی است که در پاسخ به یک Event عملیات مشخصی انجام میدهد.
چگونه Event در Laravel بسازیم؟
با دستور:
php artisan make:event OrderCreated
چگونه Listener بسازیم؟
با:
php artisan make:listener SendOrderNotification --event=OrderCreated
چگونه Event را اجرا کنیم؟
میتوان از:
event(new OrderCreated($order));
یا در صورت استفاده از Dispatchable از:
OrderCreated::dispatch($order);
استفاده کرد.
آیا یک Event میتواند چند Listener داشته باشد؟
بله. یک Event میتواند چند Listener داشته باشد و هر Listener یک وظیفه مستقل را انجام دهد.
آیا Listener میتواند Queue شود؟
بله. Listener میتواند ShouldQueue را پیادهسازی کند تا اجرای آن به Queue منتقل شود.
تفاوت Event و Notification چیست؟
Event اعلام وقوع یک اتفاق است، اما Notification برای اطلاعرسانی به یک دریافتکننده استفاده میشود.
تفاوت Event و Job چیست؟
Event میگوید اتفاقی رخ داده است؛ Job یک کار مشخص برای اجراست. در معماریهای بزرگ این دو میتوانند در کنار هم استفاده شوند.





