- نموذج تفاعلي يعتمد على الأحداث والمستمعين ووحدات التحكم
- يدعم الواجهات الرسومية والشبكات غير المتزامنة و إنترنت الأشياء في الوقت الحقيقي
- دعم متعدد المنصات لـ JS وNode.js وPython/Tkinter والأدوات المرئية
- أفضل الممارسات: التفويض، وتنظيف المستمع، وإدارة كائنات الحدث
La البرمجة موجه نحو الحدث (POE) هو النهج الذي لا يتقدم فيه التطبيق بشكل خطي، بل يتفاعل مع الأحداث فور حدوثها. فبدلاً من فرض تدفق ثابت، ينتظر النظام، عندما يتم تشغيل حدث ما (نقرة، مفتاح، رسالة شبكة، مؤقت)، يتم تنفيذ الكود المرتبط للتعامل معها.
هذا النمط موجود في كل مكان: واجهات رسومية (الويب وسطح المكتب والهاتف المحمول)، والخوادم ذات الإدخال/الإخراج غير الحظر، التطبيقات لوحات معلومات إنترنت الأشياء أو المراقبة الفورية. إذا تساءلت يومًا كيف "يعرف" التطبيق أنك ضغطت زرًا أو أن استجابة HTTP قد وصلت، فالحل يكمن في المستمعون، ووحدات التحكم، وحلقة الحدث.
ما هي البرمجة الموجهة للأحداث بالضبط؟
في الهندسة المعمارية التي تعتمد على الأحداث، يتم تنفيذ التنفيذ من خلال الأحداث التي يمكن ملاحظتها في النظام أو يُنشئه المستخدم. الحدث هو إشارة تُشير إلى حدوث شيء ما: تحريك الماوس، أو الكتابة في حقل، أو إكمال تنزيل، أو استلام حزمة على منفذ، أو يتغير المستشعر الحالة.
وللرد على هذه الأحداث يتم تسجيلها المستمعين الذين يستمعون إلى أنواع معينة من الأحداث ويرتبطون بها المعالجون تحتوي على الإجراءات المطلوب تنفيذها. ويتم تنسيق كل هذا مع حلقة الحدث، الذي يجمع الأحداث ويضعها في قائمة انتظار ويرسلها إلى وحدات التحكم الخاصة به.
المفاهيم الرئيسية التي يجب أن تعرفها
ومن المناسب التمييز بين المكونات الأساسية لهذا النموذج، لأنه توضيح المسؤوليات داخل النظام وتجنب الارتباك عند التصميم.
أحداث
الحدث هو إشعار بحدوث أمر مهم. قد يتضمن بيانات مرفقة (مثل: المفتاح الذي تم الضغط عليه أو موضع الماوس أو الحمولة من استجابة الشبكة) لكي يتمكن المتحكم من اتخاذ القرارات.
أجهزة الإرسال والاستقبال
Un مرسل هو الذي يقوم بإنشاء الحدث (زر، مقبس، مؤقت). أ المتلقي أو يستمع المشترك إلى نوع الحدث وينفذ وظيفة عندما يحدث؛ يسمح هذا الفصل قياس وإعادة تجميع السلوكيات بسهولة.
حلقة الحدث
إنه قلب النظام: يحافظ على قائمة انتظار الأحداثيعالجها بالترتيب، ويستدعي المعالجات المقابلة. يؤدي هذا إلى إنشاء تطبيقات تفاعلية تستجيب لأحداث متعددة متزامنة دون حظر الخيط الرئيسي.
المستمعون والمتحكمون
المستمع هو "الأذن" التي تسجل على عنصر أو قناة، في حين أن المتحكم هو "العقل" الذي يقرر ما يجب فعله عند التنشيطيؤدي فصلهما إلى تحسين الصيانة وتشجيع إعادة الاستخدام.

أكثر أنواع الأحداث شيوعًا
هناك العشرات، ولكن هذه المجموعات تغطي معظم الحالات؛ فهمهم يوفر عليك ساعات تصحيح الأخطاء.
الفأرة والمؤشر
| حدث | عندما يحدث ذلك |
|---|---|
| النقر | يضغط المستخدم باستخدام الماوس أو الإصبع على عنصر ما. |
| تمرير الماوس فوق / إخراج الماوس | يدخل المؤشر إلى عنصر (أو عنصر فرعي) أو يخرج منه. |
| قائمة السياق | انقر بزر الماوس الأيمن لفتح قائمة السياق. |
| تحرك الماوس | يتحرك المؤشر فوق العنصر. |
| رفع الماوس / خفض الماوس | تم الضغط على زر الماوس أو تحريره. |
النافذة والمستند
| حدث | عندما يحدث ذلك |
|---|---|
| تحميل | المتصفح لديه تم الانتهاء من التحميل الصفحة. |
| خطأ | فشل تحميل المورد (CSS، سيناريو، صورة) أو عملية أخرى. |
| انتقل | يتم تمرير العرض أو الحاوية التي تحتوي على فيضان. |
| عرض الصفحات / إخفاء الصفحات | تغييرات في رؤية علامات التبويب أو التنقل في bfcache. |
| تغيير حجم | يتم تغيير حجم نافذة المتصفح. |
أشكال
| حدث | عندما يحدث ذلك |
|---|---|
| تقدم | محاولة إرسال النموذج (قبل التنقل). |
| التركيز على / التركيز على الخارج | يكتسب عنصر (أو طفله) التركيز أو يفقده. |
| إدخال | المستخدم إدخال البيانات في عنصر التحكم (في الوقت الحقيقي). |
| تغيير | قم بتغيير القيمة ويفقد عنصر التحكم التركيز (مربع الاختيار، التحديد، الإدخال). |
لوحة المفاتيح
| حدث | عندما يحدث ذلك |
|---|---|
| keydown | تم الضغط على المفتاح. |
| مفتاح | تم تحرير المفتاح. |
| ضغط المفتاح | يتم الضغط على مفتاح الحرف ثم تحريره (ليس كل المفاتيح). |
كائن الحدث والخصائص المفيدة
عندما يتم تشغيل المستمع، يستقبل المتحكم كائنًا يحتوي على تفاصيل الحدث. تعلم كيفية الضغط عليه تجنب كتابة المنطق الهش.
الخصائص والطرق العامة:
- الهدف: العنصر الذي بدأ به الحدث.
- نوع: النوع (على سبيل المثال 'انقر فوق'، 'إدخال').
- قابلة للإلغاء: يشير إلى ما إذا كان من الممكن إلغاء الإجراء الافتراضي.
- منع التقصير:يلغي الإجراء الافتراضي (إذا كان ذلك ممكنًا).
- إيقاف الانتشار (): يوقف الانتشار (الفقاعات/الالتقاط).
إضافات متكررة حسب النوع: العميلX/الصفحةX y العميل/الصفحة في الفأرة؛ التي o زر للزر الذي تم الضغط عليه؛ مفتاح y الكود على المفاتيح؛ وعلى العجلة/التمرير، دلتا إكس / دلتا واي y وضع دلتا.
الاستماع إلى الأحداث ومعالجتها في JavaScript
على الويب، يمكنك تسجيل المستمعين باستخدام HTML أو الكود. يُنصح بذلك هيكل وسلوك منفصلين، باستخدام addEventListener.
الخيار 1: السمة المضمنة
على الرغم من أنها ليست الممارسة الأكثر نظافة، إلا أنك سترى أحيانًا شيئًا كهذا، حيث يتم استدعاء الوظيفة عندما يحدث الحدث:
<!-- myClickHandler es la función que manejará el clic -->
<button onclick='myClickHandler()'>Click</button>
<script>
function myClickHandler(){
alert('hola');
}
</script>
الخيار 2: addEventListener (مستحسن)
باستخدام هذه التقنية، يمكنك تسجيل المستمع أثناء وقت التشغيل؛ لا تستدعي الوظيفة، عليك فقط تمرير المرجع:
// index.html: <button id='b'>Borrar</button>
const btn = document.querySelector('#b');
const onClick = (e) => {
console.log('Pulsado', e.target);
};
btn.addEventListener('click', onClick);
// Eliminar el listener más tarde (mismos parámetros)
btn.removeEventListener('click', onClick);
قراءة القيمة التي أدخلها المستخدم
عند التعامل مع النماذج، قيمة الهدف هو أفضل صديق لك لالتقاط المدخلات:
<input type='text' id='nombre' />
<script>
const input = document.querySelector('#nombre');
const onChange = (e) => {
console.log('Valor:', e.target.value);
};
input.addEventListener('change', onChange);
</script>
Node.js: EventEmitter في العمل
في بيئة الخادم، يعرض Node.js نمط النشر/الاشتراك باستخدام الحدث، مثالي لتنسيق المنطق غير المتزامن، على سبيل المثال عندما إدارة السجلات والأحداث في Hyper-V، بدون وحدات اقتران.
// Ejemplo mínimo de emisor y receptor en Node.js
const { EventEmitter } = require('events');
class BusEventos extends EventEmitter {}
const bus = new BusEventos();
// Suscribimos un receptor al evento 'saludo'
bus.on('saludo', (nombre) => {
console.log(`¡Hola, ${nombre}!`);
});
// Disparamos el evento con datos asociados
bus.emit('saludo', 'mundo');
النمط يسمح بمستقبلين متعددين الرد على نفس الحدث أو أن المُصدر لا يعرف مشتركين محددين، مما يُفضّل الفصل والتقنيات الخاصة بذلك. تصفية الأحداث الهامة باستخدام Get-WinEvent.
بايثون: من جهاز إرسال بسيط إلى Tkinter
En Python يمكنك إنشاء ناقل أحداث صغير باستخدام قواميس القائمة، أو استخدام المكتبات/واجهات المستخدم الرسومية مثل com.tkinter والتي تشكل بالفعل جزءًا من حلقة حدث النافذة.
المرسل الأساسي في بايثون
يوضح هذا الهيكل العظمي كيف استدعاءات التسجيل وإطلاقها عن طريق إصدار حدث:
class Emisor:
def __init__(self):
self._suscriptores = {}
def on(self, evento, fn):
self._suscriptores.setdefault(evento, []).append(fn)
def emit(self, evento, *args, **kwargs):
for fn in self._suscriptores.get(evento, []):
fn(*args, **kwargs)
# Uso
bus = Emisor()
bus.on('saludo', lambda: print('¡Hola, mundo!'))
bus.emit('saludo')
Tkinter: ربط أحداث الماوس ولوحة المفاتيح
تعتمد واجهات المستخدم الرسومية لسطح المكتب على حلقة أحداث. في Tkinter، ربط يربط حدثًا نصيًا بوظيفة تستقبل كائن الحدث:
from tkinter import Tk, Frame
def on_key(evt):
print('Tecla:', repr(evt.char))
def on_click(evt):
frame.focus_set()
print('Click en', evt.x, evt.y)
root = Tk()
frame = Frame(root, width=200, height=120)
frame.bind('<Key>', on_key)
frame.bind('<Button-1>', on_click)
frame.pack()
root.mainloop()
لاحظ أن أحداث الماوس تعمل على أداة تحت المؤشر، في حين تؤثر اختصارات لوحة المفاتيح على الأداة التي عليها التركيز.
MIT App Inventor: الأحداث والخصائص والطرق
يتبنى App Inventor نهجًا بصريًا باستخدام الكتل التي تمثل الأحداث، والتي يجعل الأمر أسهل للمبتدئين إنشاء تطبيقات الهاتف المحمول بدون كود نصي.
حدث: كتلة يتم تشغيلها بواسطة حدث (الضغط على الزر، فتح الشاشة، إمالة الجهاز). خصائص: سمات المكون (حجم الخط، اللون، المحاذاة) التي يمكنك تعيينها أثناء التصميم أو وقت التشغيل. طرق: الإجراءات المبرمجة مسبقًا التي ينفذها أحد المكونات (على سبيل المثال، SetFocus، AddItem)، متاحة فقط في وقت التشغيل.
وبالتالي، لا يتبع التطبيق تعليمات ثابتة؛ يتفاعل مع كتل الأحداث استدعاء الأساليب أو تغيير الخصائص حسب الاقتضاء.
الأحداث التلقائية مقابل الأحداث التي يبدأها المستخدم
هناك أحداث يتم تشغيلها بواسطة النظام (على سبيل المثال، عند فتح النافذةأو نهاية التنزيل أو توقيت التوقيت أو أحداث خردوات كما اكتشاف أحداث USB في Linux) وأخرى يسببها المستخدم (النقر، الكتابة، السحب، الإيماءات). في كلتا الحالتين، يتم تنظيم المنطق حول السائقين المرتبطين.
التطبيقات العملية للنموذج الموجه بالأحداث
- واجهات المستخدم التفاعلية:يؤدي كل تفاعل (النقر أو الكتابة أو التحديد) إلى إطلاق إجراءات تعمل على تحديث الحالة أو DOM، مما يوفر تجربة سلسة.
- الاتصالات غير المتزامنة:في خوادم الويب والخدمات المصغرة، تسمح أحداث الشبكة (وصول طلب، رسالة في وسيط) عملية بدون حظر وتسلق.
- معالجة البيانات في الوقت الحقيقي:تعتمد القياس عن بعد وإنترنت الأشياء والمراقبة على أحداث المستشعر التي تؤدي إلى ردود فورية (التنبيهات والتجميعات ولوحات المعلومات)، ويمكن استكمالها بأدوات مثل عارض أحداث Windows للتحليل.
- أنظمة التشغيل والتركيز:يقوم نظام التشغيل بتوجيه الأحداث إلى التطبيق الذي يتم التركيز عليه (انظر مدير أحداث Windows). يحتفظ كل تطبيق بحلقة الأحداث الخاصة به التي تعمل على النافذة النشطة، والتي تنسيق تطبيقات متعددة الجري بالتوازي.
مزايا وعيوب
ومن بين النقاط القوية هي التفاعل الفوريالاستخدام الفعال للموارد (يتم تنفيذ الكود فقط عندما يحدث شيء ما)، والمرونة في الجمع بين المرسلين والمستقبلين.
من ناحية أخرى، يمكن أن يؤدي النظام الذي يحتوي على العديد من الأحداث والمعالجات إلى التعقيد العرضيمن الصعب تصحيح الأخطاء إذا لم يتم توثيقها جيدًا أو إذا كانت الأنماط التنظيمية الواضحة مفقودة.
أفضل الممارسات للعمل مع الأحداث
- وفد الحدث:بدلاً من تسجيل المستمعين على العديد من العقد، قم بإضافة واحد في حاوية وقرر ما يجب فعله بناءً على ذلك. الحدث المستهدف؛ هذا يقلل من الذاكرة والاقتران.
- تنظيف المستمعين:حذف مع إزالة مستمع الحدث الذين لم تعد بحاجة إليهم أو عند تفكيك المكونات (مهم في وجهات النظر الديناميكية والوجهات النظر SPA) لمنع التسربات.
- بنية الكود: يفصل الاشتراك (المستمعين) عن المنطق (المعالجات)، ويعيد استخدام الوظائف النقية لـ تسهيل الاختبارات. توثيق أنواع الأحداث وحمولتها.
- معالجة الأخطاء:اصطد الاستثناءات في المعالجات وسجل السياق (نوع الحدث والهدف والبيانات) لـ تسريع التشخيص في الانتاج.
مقارنة سريعة مع البرمجة المتسلسلة
في حين توفر البرمجة التقليدية تدفقًا يتحكم فيه المبرمج، فإن POE يمنح التحكم للمستخدم والنظام: الترتيب الحقيقي يتميز بالأحداثوهذا يتطلب التفكير من حيث الحالات وردود الأفعال وليس الخطوات الخطية.
مثال قصير كامل على الويب: من الحدث إلى العمل
دعونا نلقي نظرة على تدفق صغير مع منع الإجراء الافتراضي وقراءة البيانات، وربط العديد من الأفكار معًا في واحد نموذج مع التحقق:
<form id='f'>
<input id='email' type='email' required />
<button type='submit'>Enviar</button>
</form>
<script>
const f = document.querySelector('#f');
f.addEventListener('submit', (e) => {
e.preventDefault(); // Evita envío si hay problemas
const valor = document.querySelector('#email').value;
if (!valor.includes('@')) {
console.error('Email no válido');
return;
}
// Aquí podrías emitir un evento de aplicación o hacer fetch
console.log('Form OK. Enviando...');
});
</script>
هنا نجمع preventDefault للتحكم في التدفق وقراءة الهدف/القيمة ومعالج يقرر الإجراء التالي.
تتيح لك البرمجة الموجهة بالأحداث بناء برامج سريعة وتفاعلية، بدءًا من واجهات المستخدم الحديثة ووصولًا إلى خطوط الأنابيب الفورية. إذا استوعبت أركانها الأساسية،الأحداث والمستمعين والمعالجات وحلقة الأحداث—وإذا قمت بتطبيق الممارسات الجيدة (التفويض، والنظافة، وإمكانية التتبع)، فسيكون لديك أساس متين لإنشاء تطبيقات قوية وقابلة للتطوير وممتعة للاستخدام.
كاتب شغوف بعالم البايت والتكنولوجيا بشكل عام. أحب مشاركة معرفتي من خلال الكتابة، وهذا ما سأفعله في هذه المدونة، لأعرض لك كل الأشياء الأكثر إثارة للاهتمام حول الأدوات الذكية والبرامج والأجهزة والاتجاهات التكنولوجية والمزيد. هدفي هو مساعدتك على التنقل في العالم الرقمي بطريقة بسيطة ومسلية.
