اليوم ، في ترجمة الجزء السابع من دليل Node.js ، سنتحدث عن البرمجة غير المتزامنة ، ونأخذ في الاعتبار قضايا مثل استخدام الاسترجاعات والوعود والبناء غير المتزامن / المنتظر ، ومناقشة كيفية العمل مع الأحداث.

[ننصحك بقراءة] أجزاء أخرى من الدورة التزامن في لغات البرمجة
جافا سكريبت نفسها هي لغة برمجة متزامنة ومترابطة. هذا يعني أنه لا يمكنك إنشاء سلاسل رسائل جديدة في التعليمات البرمجية التي يتم تشغيلها بالتوازي. ومع ذلك ، فإن أجهزة الكمبيوتر غير متزامنة بطبيعتها. أي أنه يمكن تنفيذ إجراءات معينة بغض النظر عن تدفق تنفيذ البرنامج الرئيسي. في أجهزة الكمبيوتر الحديثة ، يتم تخصيص قدر معين من وقت المعالج لكل برنامج ، عندما ينفد هذا الوقت ، يعطي النظام موارد لبرنامج آخر ، لفترة من الوقت أيضًا. يتم تنفيذ هذا التحول بشكل دوري ، ويتم ذلك بسرعة كبيرة بحيث لا يمكن لأي شخص أن يلاحظ ذلك ، ونتيجة لذلك ، نعتقد أن أجهزة الكمبيوتر الخاصة بنا تنفذ العديد من البرامج في وقت واحد. ولكن هذا وهم (ناهيك عن آلات متعددة المعالجات).
في أحشاء البرامج يتم استخدام المقاطعات - الإشارات المنقولة إلى المعالج والسماح لجذب انتباه النظام. لن ندخل في التفاصيل ، أهم شيء هو أن نتذكر أن السلوك غير المتزامن ، عندما يتم إيقاف البرنامج مؤقتًا حتى اللحظة التي يحتاج فيها إلى موارد المعالج ، أمر طبيعي تمامًا. في الوقت الذي لا يقوم فيه البرنامج بتحميل النظام بالعمل ، يمكن للكمبيوتر حل المشاكل الأخرى. على سبيل المثال ، مع هذا النهج ، عندما ينتظر البرنامج استجابة لطلب شبكة مقدم إليه ، فإنه لا يمنع المعالج حتى يتم تلقي استجابة.
كقاعدة ، تكون لغات البرمجة غير متزامنة ، بعضها يعطي المبرمج القدرة على التحكم في الآليات غير المتزامنة ، إما باستخدام أدوات اللغة المدمجة أو المكتبات المتخصصة. نحن نتحدث عن لغات مثل C و Java و C # و PHP و Go و Ruby و Swift و Python. بعضها يسمح بالبرمجة بأسلوب غير متزامن ، باستخدام الخيوط ، وبدء عمليات جديدة.
تزامن جافا سكريبت
كما ذكرنا سابقًا ، تعد JavaScript لغة متزامنة مفردة. يتم تنفيذ خطوط التعليمات البرمجية المكتوبة في JS بالترتيب الذي تظهر به في النص ، واحدًا تلو الآخر. على سبيل المثال ، إليك برنامج JS عادي جدًا يوضح هذا السلوك:
const a = 1 const b = 2 const c = a * b console.log(c) doSomething()
ولكن تم إنشاء JavaScript للاستخدام في المتصفحات. كانت مهمتها الرئيسية ، في البداية ، هي تنظيم معالجة الأحداث المتعلقة بأنشطة المستخدم. على سبيل المثال ، هذه أحداث مثل
onClick
و
onMouseOver
و
onChange
و
onSubmit
وما إلى ذلك. كيف يمكن حل مثل هذه المشاكل في إطار نموذج برمجة متزامن؟
تكمن الإجابة في البيئة التي تعمل فيها JavaScript. وبالتحديد ، يسمح لك المتصفح بحل مثل هذه المشاكل بشكل فعال ، مما يمنح المبرمج واجهات برمجة التطبيقات المناسبة.
في بيئة Node.js ، توجد أدوات لتنفيذ عمليات الإدخال / الإخراج غير المحظورة ، مثل العمل مع الملفات ، وتنظيم تبادل البيانات عبر الشبكة ، وما إلى ذلك.
الاسترجاعات
إذا تحدثنا عن جافا سكريبت المستندة إلى المستعرض ، فيمكن ملاحظة أنه من المستحيل معرفة مقدمًا عندما ينقر المستخدم على زر. من أجل التأكد من أن النظام يستجيب لمثل هذا الحدث ، يتم إنشاء معالج لذلك.
يقبل معالج الأحداث دالة سيتم استدعاؤها عند وقوع الحدث. يبدو هذا:
document.getElementById('button').addEventListener('click', () => { // })
تسمى هذه الوظائف أيضًا وظائف رد الاتصال أو رد الاتصال.
رد الاتصال هو وظيفة عادية يتم تمريرها كقيمة إلى وظيفة أخرى. سيتم استدعاؤه فقط عند حدوث حدث معين. تطبق جافا سكريبت مفهوم وظائف الدرجة الأولى. يمكن تعيين هذه الوظائف للمتغيرات وتمريرها إلى وظائف أخرى (تسمى وظائف الترتيب الأعلى).
من الأساليب الشائعة في تطوير جافا سكريبت من جانب العميل عندما يتم تغليف كل كود العميل في مستمع لحدث
load
لكائن
window
، والذي يستدعي الاستدعاء الذي تم تمريره إليه بعد أن تكون الصفحة جاهزة للعمل:
window.addEventListener('load', () => { // // })
يتم استخدام الاسترجاعات في كل مكان ، وليس فقط للتعامل مع أحداث DOM. على سبيل المثال ، لقد التقينا بالفعل باستخدامهم في المؤقتات:
setTimeout(() => {
تستخدم
طلبات XHR أيضًا عمليات الاسترجاعات. في هذه الحالة ، يبدو أن تعيين دالة للخاصية المقابلة. سيتم استدعاء وظيفة مماثلة عند وقوع حدث معين. في المثال التالي ، مثل هذا الحدث هو تغيير حالة الطلب:
const xhr = new XMLHttpRequest() xhr.onreadystatechange = () => { if (xhr.readyState === 4) { xhr.status === 200 ? console.log(xhr.responseText) : console.error('error') } } xhr.open('GET', 'https://yoursite.com') xhr.send()
▍ خطأ في معالجة الاسترجاعات
لنتحدث عن كيفية معالجة الأخطاء في عمليات الاسترجاعات. توجد استراتيجية شائعة للتعامل مع مثل هذه الأخطاء ، والتي يتم استخدامها أيضًا في Node.js. وهو يتألف من حقيقة أن المعلمة الأولى لأي وظيفة رد هي كائن خطأ. إذا لم تكن هناك أخطاء ، فسيتم كتابة قيمة
null
إلى هذه المعلمة. خلاف ذلك ، سيكون هناك كائن خطأ يحتوي على وصفه ومعلومات إضافية عنه. إليك ما يبدو عليه:
fs.readFile('/file.json', (err, data) => { if (err !== null) { // console.log(err) return } // , console.log(data) })
problem مشكلة الاستدعاء
الاسترجاعات ملائمة للاستخدام في المواقف البسيطة. ومع ذلك ، كل رد هو مستوى إضافي من تداخل التعليمات البرمجية. إذا تم استخدام العديد من عمليات الاستدعاء المتداخلة ، فإن هذا يؤدي بسرعة إلى مضاعفات كبيرة في بنية الشفرة:
window.addEventListener('load', () => { document.getElementById('button').addEventListener('click', () => { setTimeout(() => { items.forEach(item => { //, - }) }, 2000) }) })
في هذا المثال ، يتم عرض 4 مستويات فقط من التعليمات البرمجية ، ولكن من الناحية العملية قد يواجه المرء عددًا كبيرًا من المستويات ، والتي تسمى عادةً "رد الاتصال". يمكنك التعامل مع هذه المشكلة باستخدام تركيبات لغة أخرى.
الوعود وعدم التزامن / الانتظار
بدءًا من معيار ES6 ، تقدم JavaScript ميزات جديدة تسهل كتابة التعليمات البرمجية غير المتزامنة ، مما يلغي الحاجة إلى عمليات الاسترجاعات. نحن نتحدث عن الوعود التي ظهرت في ES6 ، والبنية غير المتزامنة / المنتظرة التي ظهرت في ES8.
▍ وعود
الوعود (كائنات الوعد) هي إحدى طرق العمل مع تراكيب البرامج غير المتزامنة في جافا سكريبت ، مما يقلل بشكل عام من استخدام الاسترجاعات.
التعرف على الوعود
عادة ما يتم تعريف الوعود بأنها كائنات الوكيل لقيم معينة ، والتي من المتوقع ظهورها في المستقبل. الوعود تسمى أيضا "الوعود" أو "النتائج الموعودة". على الرغم من وجود هذا المفهوم لسنوات عديدة ، تم توحيد الوعود وإضافتها إلى اللغة فقط في ES2015. في ES2017 ، ظهر التصميم غير المتزامن / المنتظر ، والذي يستند إلى الوعود ، والذي يمكن اعتباره بديلاً مناسبًا. لذلك ، حتى إذا كنت لا تخطط لاستخدام وعود منتظمة ، فإن فهم كيفية عملها يعد أمرًا مهمًا للاستخدام الفعال للبناء غير المتزامن / المنتظر.
وعود العمل
بعد استدعاء الوعد ، فإنه يذهب إلى حالة معلقة. هذا يعني أن الوظيفة التي تسببت في الوعد تستمر في التنفيذ ، بينما يتم إجراء بعض الحسابات في الوعد ، وبعد ذلك يبلغ الوعد بذلك. إذا اكتملت العملية التي نفذها الوعد بنجاح ، يتم نقل الوعد إلى الحالة التي تم الوفاء بها. ويقال أنه تم حل هذا الوعد بنجاح. إذا اكتملت العملية بخطأ ، يتم وضع الوعد في الحالة المرفوضة.
لنتحدث عن العمل بالوعود.
خلق الوعود
تعطينا واجهة برمجة التطبيقات للتعامل مع الوعود المُنشئ المقابل ، والذي يتم استدعاؤه بواسطة أمر من النموذج
new Promise()
. إليك كيفية إنشاء الوعود:
let done = true const isItDoneYet = new Promise( (resolve, reject) => { if (done) { const workDone = 'Here is the thing I built' resolve(workDone) } else { const why = 'Still working on something else' reject(why) } } )
يتحقق Promis من الثابت العالمي
done
، وإذا كانت قيمته
true
، يتم حلها بنجاح. خلاف ذلك ، تم رفض الوعد. باستخدام معلمات
resolve
reject
، وهي وظائف ، يمكننا إرجاع القيم من الوعد. في هذه الحالة ، نعيد سلسلة ، ولكن هنا يمكن استخدام كائن.
العمل مع الوعود
لقد أنشأنا وعدًا أعلاه ، والآن فكر في العمل معه. يبدو هذا:
const isItDoneYet = new Promise( //... ) const checkIfItsDone = () => { isItDoneYet .then((ok) => { console.log(ok) }) .catch((err) => { console.error(err) }) } checkIfItsDone()
checkIfItsDone()
استدعاء
checkIfItsDone()
إلى تنفيذ
isItDoneYet()
isItDoneYet
isItDoneYet()
وإلى تنظيم انتظار حلها. إذا تم حل الوعد بنجاح ، فسوف يعمل رد الاتصال الذي تم تمريره إلى الأسلوب
.then()
. في حالة حدوث خطأ ، أي سيتم رفض الوعد ، ويمكن معالجته في الدالة التي تم تمريرها إلى أسلوب
.catch()
.
وعود تسلسل
طرق الوعد تعيد الوعود ، والتي تسمح لك بدمجها في سلاسل. مثال جيد على هذا السلوك هو
واجهة برمجة التطبيقات المستندة إلى المستعرض ، وهي طبقة تجريد عبر
XMLHttpRequest
. هناك حزمة npm شائعة إلى حد ما لـ Node.js تنفذ واجهة برمجة التطبيقات Fetch ، والتي سنناقشها لاحقًا. يمكن استخدام واجهة برمجة التطبيقات هذه لتحميل موارد شبكة معينة ، وبفضل إمكانية دمج الوعود في السلاسل ، لتنظيم المعالجة اللاحقة للبيانات التي تم تنزيلها. في الواقع ، عند استدعاء Fetch API من خلال استدعاء دالة
fetch()
، يتم إنشاء وعد.
تأمل في المثال التالي لتسلسل الوعود:
const fetch = require('node-fetch') const status = (response) => { if (response.status >= 200 && response.status < 300) { return Promise.resolve(response) } return Promise.reject(new Error(response.statusText)) } const json = (response) => response.json() fetch('https://jsonplaceholder.typicode.com/todos') .then(status) .then(json) .then((data) => { console.log('Request succeeded with JSON response', data) }) .catch((error) => { console.log('Request failed', error) })
نستخدم هنا
جلب عقدة حزمة
npm ومورد jsonplaceholder.typicode.com كمصدر لبيانات JSON.
في هذا المثال ، يتم استخدام الدالة
fetch()
لتحميل عنصر قائمة TODO باستخدام سلسلة من الوعود. بعد تنفيذ
fetch()
،
يتم إرجاع
استجابة تحتوي على العديد من الخصائص ، من بينها اهتمامنا بما يلي:
status
هي قيمة رقمية تمثل رمز حالة HTTP.statusText
- وصف نصي لرمز حالة HTTP ، والذي يتم تمثيله بالسلسلة " OK
حالة نجاح الطلب.
يحتوي كائن
response
على طريقة
json()
التي تُرجع وعدًا ، يتم تقديم المحتوى الذي تمت
json()
بناءً على حل JSON.
بالنظر إلى ما سبق ، فإننا نصف ما يحدث في هذا الكود. يتم تمثيل الوعد الأول في السلسلة بوظيفة
status()
التي أعلنا عنها ، والتي تتحقق من حالة الاستجابة ، وإذا كان يشير إلى فشل الطلب (أي أن رمز حالة HTTP ليس في النطاق بين 200 و 299) ، فسيتم رفض الوعد. تؤدي هذه العملية إلى حقيقة أنه لم يتم تنفيذ
.catch()
الأخرى في سلسلة الوعود
.catch()
فورًا إلى طريقة
.catch()
،
.catch()
إلى وحدة التحكم ، إلى جانب رسالة الخطأ ،
Request failed
النص.
إذا كان رمز حالة HTTP يناسبنا ،
json()
وظيفة
json()
عنها. نظرًا لأن الوعد السابق ، إذا تم حله بنجاح ، فإنه يُرجع كائن
response
، فإننا نستخدمه كقيمة إدخال للوعد الثاني.
في هذه الحالة ، نعيد بيانات JSON التي تمت معالجتها ، وبالتالي فإن الوعد الثالث يستلمها ، وبعد ذلك ، تسبقها رسالة تفيد بأن الطلب كان قادرًا على الحصول على البيانات اللازمة ، يتم عرضها في وحدة التحكم.
معالجة الخطأ
في المثال السابق ، كان لدينا طريقة
.catch()
مرتبطة بسلسلة من الوعود. إذا حدث خطأ ما في سلسلة الوعود
.catch()
خطأ ، أو إذا تبين أن أحد الوعود قد تم رفضه ، يتم نقل التحكم إلى أقرب تعبير.
.catch()
. فيما يلي الحالة التي يحدث فيها خطأ في الوعد:
new Promise((resolve, reject) => { throw new Error('Error') }) .catch((err) => { console.error(err) })
في ما يلي مثال على
.catch()
بعد رفض الوعد:
new Promise((resolve, reject) => { reject('Error') }) .catch((err) => { console.error(err) })
معالجة الأخطاء المتتالية
ماذا لو حدث خطأ في
.catch()
؟ لمعالجة هذا الخطأ ، يمكنك تضمين
.catch()
في سلسلة الوعود (وبعد ذلك يمكنك إرفاق العديد من
.catch()
بالسلسلة حسب الحاجة):
new Promise((resolve, reject) => { throw new Error('Error') }) .catch((err) => { throw new Error('Error') }) .catch((err) => { console.error(err) })
الآن دعونا نلقي نظرة على بعض الطرق المفيدة المستخدمة لإدارة الوعود.
Promise.all ()
إذا كنت بحاجة إلى تنفيذ بعض الإجراءات بعد حل العديد من الوعود ، فيمكنك القيام بذلك باستخدام الأمر
Promise.all()
. فكر في مثال:
const f1 = fetch('https://jsonplaceholder.typicode.com/todos/1') const f2 = fetch('https://jsonplaceholder.typicode.com/todos/2') Promise.all([f1, f2]).then((res) => { console.log('Array of results', res) }) .catch((err) => { console.error(err) })
في ES2015 ، ظهر بناء جملة التخصيص المدمر ؛ باستخدامه ، يمكنك إنشاء تركيبات من النموذج التالي:
Promise.all([f1, f2]).then(([res1, res2]) => { console.log('Results', res1, res2) })
هنا ، كمثال ، اعتبرنا واجهة برمجة التطبيقات جلب ، ولكن
Promise.all()
، بالطبع ، يسمح لك بالعمل مع أي وعود.
Promise.race ()
يسمح لك الأمر
Promise.race()
بتنفيذ الإجراء المحدد بعد حل أحد الوعود التي تم تمريرها إليه. يتم استدعاء الاستدعاء المقابل الذي يحتوي على نتائج هذا الوعد الأول مرة واحدة فقط. فكر في مثال:
const first = new Promise((resolve, reject) => { setTimeout(resolve, 500, 'first') }) const second = new Promise((resolve, reject) => { setTimeout(resolve, 100, 'second') }) Promise.race([first, second]).then((result) => { console.log(result)
خطأ TypeEraught غير مسبوق يحدث عند التعامل مع الوعود
إذا واجهت ، عند العمل مع الوعود ،
Uncaught TypeError: undefined is not a promise
الخطأ
Uncaught TypeError: undefined is not a promise
خطأ
Uncaught TypeError: undefined is not a promise
، تحقق من استخدام بنية
new Promise()
بدلاً من مجرد
Promise()
عند إنشاء الوعود.
▍ غير متزامن / في انتظار التصميم
بناء غير متزامن / انتظار هو نهج حديث للبرمجة غير المتزامنة وتبسيطها. يمكن تمثيل الوظائف غير المتزامنة كمجموعة من الوعود والمولدات ، وبشكل عام ، هذا البناء هو تجريد على الوعود.
يعمل التصميم غير المتزامن / المنتظر على تقليل كمية شفرة الغلاية التي يجب عليك كتابتها عند التعامل مع الوعود. عندما ظهرت الوعود في معيار ES2015 ، كانت تهدف إلى حل مشكلة إنشاء رمز غير متزامن. لقد تعاملوا مع هذه المهمة ، ولكن بعد عامين من مشاركة مخرجات معايير ES2015 و ES2017 ، أصبح من الواضح أنه لا يمكن اعتبارهم الحل النهائي للمشكلة.
إحدى المشاكل التي وعدت بحلها كانت "جحيم الاستدعاءات" الشهيرة ، لكنهم ، بحل هذه المشكلة ، خلقوا مشاكلهم الخاصة ذات الطبيعة المماثلة.
كانت الوعود عبارة عن تركيبات بسيطة يمكن للمرء أن يبني حولها شيئًا باستخدام بنية أبسط. ونتيجة لذلك ، عندما حان الوقت ، ظهر البناء غير المتزامن / المنتظر. يسمح لك استخدامه بكتابة التعليمات البرمجية التي تبدو متزامنة ، ولكنها غير متزامنة ، على وجه الخصوص ، لا تحجب الخيط الرئيسي.
كيف يعمل البناء غير المتزامن / بانتظار
تُرجع الدالة غير المتزامنة وعدًا ، كما في المثال التالي:
const doSomethingAsync = () => { return new Promise((resolve) => { setTimeout(() => resolve('I did something'), 3000) }) }
عندما تحتاج إلى استدعاء وظيفة مماثلة ، يجب عليك وضع الكلمة الرئيسية
await
قبل الأمر لاستدعائها. سيؤدي ذلك إلى أن الرمز الذي يدعوها ينتظر انتظار إذن أو رفض الوعد المقابل. وتجدر الإشارة إلى أنه يجب الإعلان عن وظيفة تستخدم الكلمة الرئيسية المنتظرة باستخدام
async
:
const doSomething = async () => { console.log(await doSomethingAsync()) }
اجمع بين شطري الكود أعلاه وفحص سلوكها:
const doSomethingAsync = () => { return new Promise((resolve) => { setTimeout(() => resolve('I did something'), 3000) }) } const doSomething = async () => { console.log(await doSomethingAsync()) } console.log('Before') doSomething() console.log('After')
سيخرج هذا الرمز ما يلي:
Before After I did something
النص
I did something
يدخل إلى وحدة التحكم مع تأخير لمدة 3 ثوانٍ.
حول الوعود والوظائف غير المتزامنة
إذا أعلنت عن وظيفة معينة باستخدام
async
، فسيعني ذلك أن هذه الوظيفة ستعيد الوعد حتى لو لم يتم ذلك بشكل صريح. لهذا السبب ، على سبيل المثال ، المثال التالي هو رمز العمل:
const aFunction = async () => { return 'test' } aFunction().then(console.log) // 'test'
هذا التصميم مشابه لما يلي:
const aFunction = async () => { return Promise.resolve('test') } aFunction().then(console.log)
قدرات عدم التزامن / انتظار
بتحليل الأمثلة أعلاه ، يمكنك أن ترى أن الكود الذي يستخدم المتزامن / الانتظار أبسط من الكود الذي يستخدم تسلسل الوعود ، أو الكود بناءً على وظائف الاستدعاء. هنا ، بالطبع ، نظرنا في أمثلة بسيطة للغاية. يمكنك تجربة الفوائد المذكورة أعلاه بالكامل من خلال العمل مع رمز أكثر تعقيدًا. إليك ، على سبيل المثال ، كيفية تحميل بيانات JSON وتحليلها باستخدام الوعود:
const getFirstUserData = () => { return fetch('/users.json') // .then(response => response.json()) // JSON .then(users => users[0]) // .then(user => fetch(`/users/${user.name}`)) // .then(userResponse => userResponse.json()) // JSON } getFirstUserData()
إليك ما يبدو عليه الحل لنفس المشكلة باستخدام المتزامن / الانتظار:
const getFirstUserData = async () => { const response = await fetch('/users.json') // const users = await response.json() // JSON const user = users[0] // const userResponse = await fetch(`/users/${user.name}`) // const userData = await userResponse.json() // JSON return userData } getFirstUserData()
باستخدام تسلسلات من وظائف غير متزامنة
يمكن بسهولة دمج الوظائف غير المتزامنة في تصميمات تشبه سلاسل Promise. ومع ذلك ، فإن نتائج هذا المزيج هي قراءة أفضل بكثير:
const promiseToDoSomething = () => { return new Promise(resolve => { setTimeout(() => resolve('I did something'), 10000) }) } const watchOverSomeoneDoingSomething = async () => { const something = await promiseToDoSomething() return something + ' and I watched' } const watchOverSomeoneWatchingSomeoneDoingSomething = async () => { const something = await watchOverSomeoneDoingSomething() return something + ' and I watched as well' } watchOverSomeoneWatchingSomeoneDoingSomething().then((res) => { console.log(res) })
سيخرج هذا الرمز النص التالي:
I did something and I watched and I watched as well
تصحيح الأخطاء المبسطة
من الصعب تصحيح الوعود ، لأنه باستخدامها لا يمكنك استخدام الأدوات المعتادة لمصحح الأخطاء (مثل "تجاوز خطوة" ، خطوة خطوة). يمكن تصحيح التعليمات البرمجية المكتوبة باستخدام async / انتظار باستخدام نفس الأساليب مثل التعليمات البرمجية المتزامنة العادية.
توليد الأحداث في Node.js
إذا كنت تعمل مع JavaScript في متصفح ، فأنت تعلم أن الأحداث تلعب دورًا كبيرًا في التعامل مع تفاعلات المستخدم مع الصفحات. يتعلق الأمر بمعالجة الأحداث التي تسببها النقرات وحركات الماوس وضغطات المفاتيح على لوحة المفاتيح وما إلى ذلك. في Node.js ، يمكنك العمل مع الأحداث التي ينشئها المبرمج بمفرده. هنا يمكنك إنشاء نظام الأحداث الخاص بك باستخدام وحدة
الأحداث . على وجه الخصوص ، تقدم لنا هذه الوحدة فئة
EventEmitter
، التي يمكن استخدامها في تنظيم العمل مع الأحداث. قبل استخدام هذه الآلية ، تحتاج إلى توصيلها:
const EventEmitter = require('events').EventEmitter
عند العمل معها ، تتوفر لدينا طرق
on()
و
emit()
، من بين أمور أخرى.
emit
استخدام طريقة
emit
لاستدعاء الأحداث. يتم استخدام الأسلوب on لتكوين عمليات الاسترجاعات ومعالجات الأحداث التي يتم استدعاؤها عند استدعاء حدث معين.
على سبيل المثال ، لنقم بإنشاء حدث
start
. عندما يحدث ذلك ، سنقوم بإخراج شيء ما إلى وحدة التحكم:
eventEmitter = new EventEmitter(); eventEmitter.on('start', () => { console.log('started') })
من أجل تشغيل هذا الحدث ، يتم استخدام البناء التالي:
eventEmitter.emit('start')
نتيجة لتنفيذ هذا الأمر ، يتم استدعاء معالج الأحداث وتصل السلسلة إلى وحدة التحكم.
يمكنك تمرير الوسيطات إلى معالج الأحداث ، وتمثيلها كوسيطات إضافية لطريقة
emit()
:
eventEmitter.on('start', (number) => { console.log(`started ${number}`) }) eventEmitter.emit('start', 23)
يحدث الشيء نفسه في الحالات التي يحتاج فيها المعالج إلى تمرير العديد من الحجج:
eventEmitter.on('start', (start, end) => { console.log(`started from ${start} to ${end}`) }) eventEmitter.emit('start', 1, 100)
EventEmitter
فئة
EventEmitter
على بعض الطرق المفيدة الأخرى:
once()
- يسمح لك بتسجيل معالج أحداث يمكن استدعاؤه مرة واحدة فقط.removeListener()
- يسمح لك بإزالة المعالج الذي تم تمريره إليه من مصفوفة معالجات الحدث الذي تم تمريره إليه.removeAllListeners()
- يسمح لك بإزالة جميع معالجات الحدث الذي تم تمريره إليه.
الملخص
تحدثنا اليوم عن البرمجة غير المتزامنة في جافا سكريبت ، على وجه الخصوص ، ناقشنا عمليات الاسترداد والوعود والبنية غير المتزامنة / التي تنتظر. هنا تطرقنا إلى مسألة العمل مع الأحداث التي وصفها المطور باستخدام وحدة
events
. سيكون موضوعنا التالي هو آليات التواصل لمنصة Node.js.
أعزائي القراء! عند البرمجة لـ Node.js ، هل تستخدم البناء المتزامن / الذي ينتظر؟