اختار المؤلف صندوق الإنترنت المفتوح / صندوق الحرية في التعبير لتلقي تبرع كجزء من برنامج الكتابة من أجل التبرعات.
المقدمة
بالنسبة للعديد من البرامج في جافا سكريبت، يتم تنفيذ الشفرة كما يكتبها المطور – سطرا بعد الآخر. ويُطلق على هذا النوع من التنفيذ اسم التنفيذ المتزامن، لأن الأسطر تُنفذ واحدة تلو الأخرى، في النظام الذي كُتبت به. ومع ذلك، ليس كل تعليمة تُعطى للكمبيوتر بحاجة للانتظار على الفور. على سبيل المثال، إذا قمت بإرسال طلب شبكة، فإن العملية التي تنفذ الشفرة الخاصة بك ستضطر إلى الانتظار حتى يعود البيانات قبل أن تعمل عليها. في هذه الحالة، سيتم إضاعة الوقت إذا لم تُنفذ شفرة أخرى بينما تنتظر العملية لإكمال طلب الشبكة. لحل هذه المشكلة، يستخدم المطورون البرمجة الغير متزامنة، حيث يتم تنفيذ أسطر الشفرة بترتيب مختلف عن الذي كُتبت به. باستخدام البرمجة الغير متزامنة، يمكننا تنفيذ شفرة أخرى بينما ننتظر الأنشطة الطويلة مثل طلبات الشبكة لإنهاء عملها.
تُنفَّذُ رمز JavaScript على خيط واحد داخل عملية الكمبيوتر. يُعالجُ رمزه بشكل متزامن على هذا الخيط، حيثُ يُشغَّلُ تعليمةً واحدةً في كل مرةٍ. لذلك، إذا قمنا بمهمةٍ طويلة الأمد على هذا الخيط، فإن كل الرمز المتبقي يُحجَبُ حتى اكتمال المهمة. بتسخير ميزات البرمجة غير المتزامنة في JavaScript، يُمكننا تفريغ المهام الطويلة الأمد إلى خيط خلفي لتجنب هذه المشكلة. عند اكتمال المهمة، يتم وضع الرمز الذي نحتاج إلى معالجة بيانات المهمة مرة أخرى على الخيط الرئيسي الواحد.
في هذا البرنامج التعليمي، ستتعلم كيفية إدارة المهام غير المتزامنة في JavaScript بمساعدة حلقة الأحداث، وهي بنية JavaScript تكمِّل مهمة جديدة أثناء انتظار أخرى. بعد ذلك، ستقوم بإنشاء برنامج يستخدم البرمجة غير المتزامنة لطلب قائمة بالأفلام من واجهة برمجة تطبيقات Studio Ghibli وحفظ البيانات في ملف CSV. سيتم كتابة الرمز غير المتزامن بثلاث طرق: استدعاء العودة، الوعود، وباستخدام الكلمات الرئيسية async/await.
ملاحظة: حتى تاريخ كتابة هذا المقال، لم يعد استخدام البرمجة غير المتزامنة يعتمد فقط على استدعاءات العودة، ولكن تعلم هذه الطريقة القديمة يمكن أن يوفر سياقًا رائعًا لماذا تستخدم مجتمع JavaScript الوعود الآن. تمكِّننا كلمات الرئيسية async/await من استخدام الوعود بطريقة أقل حجمًا، وبالتالي فهي الطريقة القياسية للقيام بالبرمجة غير المتزامنة في JavaScript حتى تاريخ كتابة هذا المقال.
المتطلبات
- يجب تثبيت Node.js على جهاز التطوير الخاص بك. يستخدم هذا البرنامج التعليمي الإصدار 10.17.0. لتثبيت هذا على macOS أو Ubuntu 18.04 ، اتبع الخطوات في كيفية تثبيت Node.js وإنشاء بيئة تطوير محلية على macOS أو القسم التثبيت باستخدام PPA من كيفية تثبيت Node.js على Ubuntu 18.04.
- سيكون لديك أيضًا الحاجة إلى التعرف على كيفية تثبيت الحزم في مشروعك. ابدأ في السرعة من خلال قراءة دليلنا على كيفية استخدام وحدات Node.js مع npm و package.json.
- من المهم أن تكون مرتاحًا في إنشاء وتنفيذ الوظائف في JavaScript قبل أن تتعلم كيفية استخدامها بشكل غير متزامن. إذا كنت بحاجة إلى مقدمة أو مراجعة ، يمكنك قراءة دليلنا على كيفية تعريف الوظائف في JavaScript
حلقة الأحداث
دورة الحدث
لنبدأ بدراسة آلية عمل تنفيذ وظائف JavaScript الداخلية. فهم كيف يتصرف هذا سيسمح لك بكتابة كود متزامن بشكل عنيد أكثر، وسيساعدك في إصلاح الكود في المستقبل.
عندما يقوم مترجم JavaScript بتنفيذ التعليمات البرمجية، يتم إضافة كل وظيفة مكالمة إلى كومة المكالمات في JavaScript. تعتبر كومة المكالمات كومة – بنية بيانات شبيهة بالقائمة حيث يمكن إضافة العناصر فقط إلى القمة، وإزالتها من القمة. تتبع المكدسات مبدأ “آخر دخول، أول سحب” أو LIFO. إذا قمت بإضافة عنصرين إلى المكدس، فإن العنصر الأخير المضاف يتم إزالته أولاً.
دعونا نوضح بمثال باستخدام كومة المكالمات. إذا قابل JavaScript وظيفة functionA()
، يتم إضافتها إلى كومة المكالمات. إذا كانت تلك الوظيفة functionA()
تطلق وظيفة أخرى functionB()
، فإن functionB()
يتم إضافتها إلى قمة كومة المكالمات. عندما يكمل JavaScript تنفيذ وظيفة، يتم إزالتها من كومة المكالمات. لذلك، سيقوم JavaScript بتنفيذ functionB()
أولاً، وإزالتها من المكدس عند الانتهاء، ثم الانتهاء من تنفيذ functionA()
وإزالتها من كومة المكالمات. لهذا السبب يتم تنفيذ الوظائف الداخلية دائمًا قبل وظائفها الخارجية.
عندما يواجه JavaScript عملية غير متزامنة، مثل الكتابة إلى ملف، يُضيفها إلى جدول في ذاكرته. يخزن هذا الجدول العملية، والشرط لاستكمالها، والدالة التي يجب استدعاؤها عند اكتمالها. كلما اكتملت العملية، يضيف JavaScript الدالة المرتبطة بها إلى طابور الرسائل. الطابور هو هيكل بيانات مشابه للقائمة حيث لا يمكن إضافة العناصر إلا في الأسفل وإزالتها من الأعلى. في طابور الرسائل، إذا كانت عمليتان أو أكثر غير متزامنة جاهزة لتنفيذ دوالها، ستكون العملية غير المتزامنة التي اكتملت أولاً لها دالتها محددة للتنفيذ أولاً.
الدوال في طابور الرسائل في انتظار إضافتها إلى كومة الاستدعاء. الحلقة الحدثية هي عملية دائمة تتحقق مما إذا كانت كومة الاستدعاء فارغة. إذا كانت كذلك، يتم نقل أول عنصر في طابور الرسائل إلى كومة الاستدعاء. يعطي JavaScript الأولوية للدوال في طابور الرسائل على الدوال التي يفسرها في الشيفرة. الآثار المجتمعة لكومة الاستدعاء، وطابور الرسائل، والحلقة الحدثية تسمح لشيفرة JavaScript بالمعالجة بينما تدير الأنشطة غير المتزامنة.
الآن بعد أن لديك فهم عالي المستوى للحلقة الحدثية، تعرف كيف سيتم تنفيذ الشيفرة غير المتزامنة التي تكتبها. باستخدام هذا المعرفة، يمكنك الآن إنشاء شيفرة غير متزامنة باستخدام ثلاثة نهج مختلفة: التعامل مع الاستدعاءات، الوعود، و async
/await
.
البرمجة الغير متزامنة باستخدام التعامل مع الاستدعاءات
A callback function is one that is passed as an argument to another function, and then executed when the other function is finished. We use callbacks to ensure that code is executed only after an asynchronous operation is completed.
لفترة طويلة، كانت الاستدعاءات هي الآلية الأكثر شيوعًا لكتابة الشفرة غير المتزامنة، ولكن الآن أصبحت في الغالب قديمة لأنها يمكن أن تجعل الشفرة مربكة للقراءة. في هذه الخطوة، ستقوم بكتابة مثال على الشفرة غير المتزامنة باستخدام الاستدعاءات حتى تتمكن من استخدامه كقاعدة لرؤية الكفاءة المتزايدة لاستراتيجيات أخرى.
هناك العديد من الطرق لاستخدام وظائف الاستدعاء في دالة أخرى. بشكل عام، تأخذ هذه الهيكل:
على الرغم من أنه ليس من الضروري بناءً على الصياغة في جافا سكريبت أو نود.جي.إس أن يكون دالة الاستدعاء كآخر وسيط للدالة الخارجية، إلا أنه من الممارسات الشائعة التي تجعل الاستدعاءات أسهل في التعرف عليها. كما أنه من الشائع أيضًا على مطوري جافا سكريبت استخدام دالة مجهولة الاسم كاستدعاء. الدوال المجهولة الاسم هي تلك التي يتم إنشاؤها بدون اسم. عادةً ما يكون أكثر قراءة عندما تكون الدالة محددة في نهاية قائمة الوسائط.
لتوضيح الاستدعاءات، دعونا ننشئ وحدة Node.js تكتب قائمة بأفلام استوديو غيبلي إلى ملف. أولاً، قم بإنشاء مجلد سيحتوي على ملف JavaScript لدينا والمخرجات الخاصة به:
ثم ادخل إلى هذا المجلد:
سنبدأ بعمل طلب HTTP إلى واجهة برمجة تطبيقات استوديو غيبلي، الذي ستسجله دالتنا المستدعاة نتائجه. للقيام بذلك، سنقوم بتثبيت مكتبة تتيح لنا الوصول إلى بيانات استجابة HTTP في دالة استدعاء.
في الطرفية الخاصة بك، قم بتهيئة npm حتى نتمكن من الرجوع إلى حزمنا لاحقًا: request
ثم، قم بتثبيت مكتبة request
:
الآن افتح ملفًا جديدًا يسمى callbackMovies.js
في محرر نص مثل nano
:
في محرر النص الخاص بك، أدخل التعليمات البرمجية التالية. لنبدأ بإرسال طلب HTTP باستخدام وحدة request
:
في السطر الأول، نحمل وحدة request
التي تم تثبيتها عبر npm. تُرجع الوحدة وظيفة يمكنها إرسال طلبات HTTP؛ ثم نحفظ تلك الوظيفة في الثابت request
.
ثم نقوم بإرسال طلب HTTP باستخدام الدالة request()
. دعونا الآن نطبع بيانات الطلب HTTP على وحدة التحكم عن طريق إضافة التغييرات المظللة:
عندما نستخدم الدالة request()
، نعطيها معلمتين:
- عنوان URL الموقع الذي نحاول طلبه
- A callback function that handles any errors or successful responses after the request is complete
دالة المكالمة المتصلة (callback) الخاصة بنا لديها ثلاثة أعضاء: error
، response
، و body
. عندما يكتمل طلب HTTP، يتم تعيين القيم تلقائيًا بناءً على النتيجة. إذا فشل الطلب في الإرسال، فإن error
سيحتوي على كائن، لكن response
و body
سيكونا null
. إذا تم إرسال الطلب بنجاح، فإن الاستجابة التي حصل عليها HTTP تُخزّن في response
. إذا أرجع طلب HTTP الخاص بنا بيانات (في هذا المثال نحصل على JSON) ، فإن البيانات تُضاف في body
.
تقوم وظيفة الرد الخاصة بنا أولاً بالتحقق مما إذا كنا قد تلقينا خطأ. من الممارسات الجيدة التحقق من الأخطاء في الرد أولاً حتى لا يستمر تنفيذ الرد بدون بيانات مفقودة. في هذه الحالة، نقوم بتسجيل الخطأ وتنفيذ الوظيفة. ثم نتحقق من كود الحالة في الاستجابة. قد لا يكون خادمنا متاحًا دائمًا، ويمكن أن تتغير واجهات برمجة التطبيقات مما يؤدي إلى طلبات منطقية مرة واحدة لتصبح غير صحيحة. من خلال التحقق من أن كود الحالة هو 200
، مما يعني أن الطلب كان “موافق”، يمكننا أن نكون واثقين من أن الاستجابة هي ما نتوقعه.
أخيرًا، نقوم بتحليل جسم الاستجابة إلى Array
ونكرر كل فيلم لتسجيل اسمه وسنة الإصدار.
بعد حفظ الملف وإغلاقه، قم بتشغيل هذا النص بالأمر التالي:
ستحصل على الناتج التالي:
OutputCastle in the Sky, 1986
Grave of the Fireflies, 1988
My Neighbor Totoro, 1988
Kiki's Delivery Service, 1989
Only Yesterday, 1991
Porco Rosso, 1992
Pom Poko, 1994
Whisper of the Heart, 1995
Princess Mononoke, 1997
My Neighbors the Yamadas, 1999
Spirited Away, 2001
The Cat Returns, 2002
Howl's Moving Castle, 2004
Tales from Earthsea, 2006
Ponyo, 2008
Arrietty, 2010
From Up on Poppy Hill, 2011
The Wind Rises, 2013
The Tale of the Princess Kaguya, 2013
When Marnie Was There, 2014
لقد تلقينا بنجاح قائمة بأفلام ستوديو غيبلي مع السنة التي تم إصدارها فيها. الآن دعنا نكمل هذا البرنامج بكتابة قائمة الأفلام التي نقوم حاليًا بتسجيلها في ملف.
قم بتحديث ملف callbackMovies.js
في محرر النص الخاص بك لتضمين الكود المميز التالي، الذي ينشئ ملف CSV باستخدام بيانات الفيلم الخاصة بنا:
ملاحظة التغييرات المميزة، نرى أننا نقوم بأستيراد وحدة fs
. تعد هذه الوحدة قياسية في جميع تثبيتات Node.js، وتحتوي على طريقة writeFile()
التي يمكنها كتابة الملف بشكل غير متزامن.
بدلاً من تسجيل البيانات في وحدة التحكم، نقوم الآن بإضافتها إلى متغير سلسلة movieList
. ثم نستخدم writeFile()
لحفظ محتويات movieList
في ملف جديد – callbackMovies.csv
. وأخيرًا، نقدم وظيفة رد الاتصال إلى دالة writeFile()
، التي تحتوي على وسيط واحد: error
. يتيح لنا هذا التعامل مع الحالات التي لا يمكننا فيها كتابة الملف، على سبيل المثال عندما لا يكون للمستخدم الذي نقوم بتشغيل عملية node
عليه تلك الأذونات.
احفظ الملف وقم بتشغيل برنامج Node.js هذا مرة أخرى باستخدام:
في مجلد ghibliMovies
الخاص بك، سترى callbackMovies.csv
، الذي يحتوي على المحتوى التالي:
Castle in the Sky, 1986
Grave of the Fireflies, 1988
My Neighbor Totoro, 1988
Kiki's Delivery Service, 1989
Only Yesterday, 1991
Porco Rosso, 1992
Pom Poko, 1994
Whisper of the Heart, 1995
Princess Mononoke, 1997
My Neighbors the Yamadas, 1999
Spirited Away, 2001
The Cat Returns, 2002
Howl's Moving Castle, 2004
Tales from Earthsea, 2006
Ponyo, 2008
Arrietty, 2010
From Up on Poppy Hill, 2011
The Wind Rises, 2013
The Tale of the Princess Kaguya, 2013
When Marnie Was There, 2014
من المهم أن نلاحظ أننا نكتب إلى ملف CSV الخاص بنا في رد الاتصال لطلب HTTP. عندما يكون الكود في دالة الرد، فإنه سيقوم بكتابة الملف فقط بعد اكتمال طلب HTTP. إذا أردنا التواصل مع قاعدة بيانات بعد كتابة ملف CSV الخاص بنا، فسنقوم بإنشاء وظيفة غير متزامنة أخرى ستُستدعى في رد الاتصال لـ writeFile()
. كلما زاد الكود غير المتزامن الذي لدينا، زاد عدد وظائف الرد.
لنتخيل أننا نريد تنفيذ خمس عمليات غير متزامنة، كل منها قادر فقط على التشغيل عندما يكتمل آخر. إذا كنا سنبرمج هذا، سنكون لدينا شيء مثل هذا:
عندما يحتوي التداخل المتداخل على العديد من الأسطر للتنفيذ، يصبح أكثر تعقيدًا وعدم قراءة. مع نمو مشروعك في جافا سكريبت من حيث الحجم والتعقيد، سيصبح هذا التأثير أكثر وضوحًا، حتى يصبح غير قابل للإدارة في نهاية المطاف. وبسبب ذلك، لم يعد المطورون يستخدمون التداعيات للتعامل مع العمليات الغير متزامنة. لتحسين بناء جملة شفرتنا الغير متزامنة، يمكننا استخدام الوعود بدلاً من ذلك.
A promise is a JavaScript object that will return a value at some point in the future. Asynchronous functions can return promise objects instead of concrete values. If we get a value in the future, we say that the promise was fulfilled. If we get an error in the future, we say that the promise was rejected. Otherwise, the promise is still being worked on in a pending state.
تستخدم الوعود بشكل عام الشكل التالي:
كما هو موضح في هذا القالب، تستخدم الوعود أيضًا وظائف التداعيات. لدينا وظيفة تداعيات لطريقة then()
، التي يتم تنفيذها عندما يتم تحقيق الوعد. لدينا أيضًا وظيفة تداعيات لطريقة catch()
للتعامل مع أي أخطاء تحدث أثناء تنفيذ الوعد.
دعنا نحصل على تجربة مباشرة مع الوعود عن طريق إعادة كتابة برنامج ستوديو جيبلي الخاص بنا لاستخدام الوعود بدلاً من ذلك.
Axios هو عميل HTTP مبني على الوعود لجافا سكريبت، لذا دعنا نقوم بتثبيته:
الآن، باستخدام محرر النص الخاص بك المفضل، قم بإنشاء ملف جديد promiseMovies.js
:
سيقوم برنامجنا بإجراء طلب HTTP مع axios
ثم استخدام نسخة وعودية خاصة من fs
للحفظ في ملف CSV جديد.
قم بكتابة هذا الكود في promiseMovies.js
حتى نتمكن من تحميل Axios وإرسال طلب HTTP إلى واجهة برمجة التطبيقات الخاصة بالأفلام:
في السطر الأول نقوم بتحميل وحدة الـ axios
، مخزنين الدالة المُرجعة في ثابت يُسمى axios
. ثم نستخدم طريقة axios.get()
لإرسال طلب HTTP إلى واجهة برمجة التطبيقات.
تُعيد طريقة axios.get()
وعدًا. لنقم بربط تلك الوعدة حتى نتمكن من طباعة قائمة أفلام Ghibli إلى وحدة التحكم:
لنقم بتحليل ما يحدث. بعد إجراء طلب GET HTTP بواسطة axios.get()
، نستخدم الدالة then()
، التي لا تُنفَذ إلا عندما يتم تحقيق الوعد. في هذه الحالة، نقوم بطباعة الأفلام إلى الشاشة كما فعلنا في مثال التعريفات الخاصة بالإستدعاءات الرجوعية.
لتحسين هذا البرنامج، أضف الشيفرة المحددة لكتابة البيانات HTTP إلى ملف:
نقوم بإستيراد وحدة fs
إضافية مرة أخرى. لاحظ كيف أنه بعد إستيراد fs
لدينا .promises
. يتضمن Node.js نسخة معدلة للوعود من مكتبة الـ fs
المعتمدة على الإستدعاءات الرجوعية، لذا لا يتم كسر التوافق الخلفي في المشاريع القديمة.
الدالة then()
الأولى التي تُعالج طلب الـ HTTP الآن تستدعي fs.writeFile()
بدلاً من الطباعة إلى وحدة التحكم. نظرًا لأننا قمنا بإستيراد النسخة المعتمدة على الوعود من fs
، فإن دالتنا writeFile()
تُعيد وعدًا آخر. لذا، نضيف دالة then()
أخرى للتعامل مع وعد writeFile()
عند تحقيقه.
A promise can return a new promise, allowing us to execute promises one after the other. This paves the way for us to perform multiple asynchronous operations. This is called promise chaining, and it is analogous to nesting callbacks. The second then()
is only called after we successfully write to the file.
ملاحظة: في هذا المثال، لم نتحقق من رمز حالة HTTP كما فعلنا في مثال الاستدعاء. بشكل افتراضي، axios
لا يفي بوعده إذا حصل على رمز حالة يشير إلى خطأ. وبالتالي، لم نعد بحاجة إلى التحقق منه.
لإكمال هذا البرنامج، قم بربط الوعد بوظيفة catch()
كما هو موضح فيما يلي:
إذا لم يتم تحقيق أي وعد في سلسلة الوعود، ينتقل JavaScript تلقائيًا إلى وظيفة catch()
إذا تم تعريفها. لهذا السبب، لدينا فقط تعليمة واحدة catch()
على الرغم من وجود عمليتين غير متزامنتين.
دعنا نتأكد من أن برنامجنا ينتج نفس الناتج من خلال تشغيل:
في مجلد ghibliMovies
الخاص بك، سترى ملف promiseMovies.csv
الذي يحتوي على:
Castle in the Sky, 1986
Grave of the Fireflies, 1988
My Neighbor Totoro, 1988
Kiki's Delivery Service, 1989
Only Yesterday, 1991
Porco Rosso, 1992
Pom Poko, 1994
Whisper of the Heart, 1995
Princess Mononoke, 1997
My Neighbors the Yamadas, 1999
Spirited Away, 2001
The Cat Returns, 2002
Howl's Moving Castle, 2004
Tales from Earthsea, 2006
Ponyo, 2008
Arrietty, 2010
From Up on Poppy Hill, 2011
The Wind Rises, 2013
The Tale of the Princess Kaguya, 2013
When Marnie Was There, 2014
مع الوعود، يمكننا كتابة رمز أكثر انتظامًا بكثير من استخدام المداخل فقط. سلسلة الوعود بالمداخل هي خيار أنظف من تضمين المداخل. ومع ذلك، كلما قمنا بإجراء المزيد من الاستدعاءات غير المتزامنة، تصبح سلسلة الوعود أطول وأصعب في الصيانة.
الطول المفرط للمداخل والوعود يأتي من الحاجة إلى إنشاء وظائف عندما نحصل على نتيجة مهمة غير متزامنة. تجربة أفضل ستكون بانتظار نتيجة غير متزامنة ووضعها في متغير خارج الوظيفة. بهذه الطريقة، يمكننا استخدام النتائج في المتغيرات دون الحاجة إلى إنشاء وظيفة. يمكننا تحقيق هذا باستخدام الكلمات المفتاحية async
و await
.
كتابة JavaScript مع async/await
الكلمات المفتاحية async/await توفر بنية بديلة عند العمل مع الوعود. بدلاً من وجود نتيجة الوعد متاحة في طريقة then()، يتم إرجاع النتيجة كقيمة مثل أي دالة أخرى. نقوم بتعريف دالة باستخدام الكلمة الرئيسية async لإخبار JavaScript بأنها دالة غير متزامنة تُرجع وعدًا. نستخدم كلمة await لإخبار JavaScript بإرجاع نتائج الوعد بدلاً من إرجاع الوعد نفسه عندما يتم تحقيقه.
بشكل عام، يبدو استخدام async/await مثل هذا:
لنرى كيف يمكن استخدام async/await لتحسين برنامج Studio Ghibli الخاص بنا. استخدم محرر النصوص لإنشاء ملف جديد وافتحه باسم asyncAwaitMovies.js:
في ملف JavaScript الجديد الذي تم فتحه، دعنا نبدأ بالاستيراد نفس الوحدات التي استخدمناها في مثال الوعد:
الاستيرادات هي نفسها كما في promiseMovies.js لأن async/await تستخدم الوعود.
الآن نستخدم الكلمة الرئيسية async لإنشاء دالة مع الكود غير المتزامن الخاص بنا:
نقوم بإنشاء وظيفة جديدة تسمى
saveMovies()
ولكننا نضمن وجود async
في بداية تعريفها. هذا مهم لأننا يمكن أن نستخدم الكلمة الرئيسية await
فقط في وظيفة غير متزامنة.
نستخدم الكلمة الرئيسية await
لإجراء طلب HTTP يحصل على قائمة الأفلام من API جيبلي:
في وظيفتنا saveMovies()
، نقوم بعمل طلب HTTP باستخدام axios.get()
كما فعلنا من قبل. هذه المرة، لا نقوم بربطها بوظيفة then()
. بدلاً من ذلك، نضيف await
قبل استدعائها. عندما يرى JavaScript await
، سينفذ الشيفرة المتبقية من الوظيفة فقط بعد انتهاء تنفيذ axios.get()
وتعيين المتغير response
. الشيفرة الأخرى تقوم بحفظ بيانات الفيلم حتى نتمكن من الكتابة إلى ملف.
لنكتب بيانات الفيلم إلى ملف:
نستخدم أيضًا الكلمة الرئيسية await
عندما نكتب إلى الملف باستخدام fs.writeFile()
.
لإكمال هذه الوظيفة، نحتاج إلى التقاط الأخطاء التي يمكن أن تقذفها الوعود لدينا. دعونا نفعل ذلك عن طريق تضمين شيفرتنا في كتلة try
/catch
:
نظرًا لأن الوعود قد تفشل، نقوم بتغليف شيفرتنا الغير متزامنة بعبارة try
/catch
. سيتم ذلك لالتقاط أي أخطاء يتم رميها عند فشل عمليات الطلب HTTP أو كتابة الملف.
أخيرًا، دعونا نستدعي وظيفتنا الغير متزامنة saveMovies()
حتى يتم تنفيذها عند تشغيل البرنامج بواسطة node
.
عند النظرة الأولى، يبدو هذا مثل كود JavaScript متزامن نموذجي. يحتوي على أقل عدد من الدوال التي يتم تمريرها، مما يبدو أكثر نظافة. هذه التعديلات الصغيرة تجعل كود اللا مزامن مع async
/await
أسهل للصيانة.
اختبر هذا الإصدار من برنامجنا من خلال إدخال هذا في الطرفية الخاصة بك:
سيتم إنشاء ملف جديد بعنوان asyncAwaitMovies.csv
في مجلد ghibliMovies
بالمحتويات التالية:
Castle in the Sky, 1986
Grave of the Fireflies, 1988
My Neighbor Totoro, 1988
Kiki's Delivery Service, 1989
Only Yesterday, 1991
Porco Rosso, 1992
Pom Poko, 1994
Whisper of the Heart, 1995
Princess Mononoke, 1997
My Neighbors the Yamadas, 1999
Spirited Away, 2001
The Cat Returns, 2002
Howl's Moving Castle, 2004
Tales from Earthsea, 2006
Ponyo, 2008
Arrietty, 2010
From Up on Poppy Hill, 2011
The Wind Rises, 2013
The Tale of the Princess Kaguya, 2013
When Marnie Was There, 2014
لقد استخدمت الآن ميزات JavaScript async
/await
لإدارة الكود غير المتزامن.
الختام
في هذا البرنامج التعليمي، تعلمت كيفية تنفيذ الدوال وإدارة العمليات غير المتزامنة في JavaScript باستخدام حلقة الأحداث. ثم كتبت برامج أنشأت ملف CSV بعد عمل طلب HTTP لبيانات الأفلام باستخدام تقنيات برمجة غير متزامنة مختلفة. أولاً، استخدمت الطريقة المبنية على الاستدعاءات المتجاوبة القديمة. ثم استخدمت الوعود، وأخيرًا async
/await
لجعل بنية الوعد أكثر إيجازًا.
مع فهمك للكود الغير متزامن بـ Node.js، يمكنك الآن تطوير برامج تستفيد من البرمجة غير المتزامنة، مثل تلك التي تعتمد على استدعاءات واجهة برمجة التطبيقات (APIs). انظر إلى هذه القائمة من الـ APIs العامة. لاستخدامها، ستحتاج إلى إجراء طلبات HTTP غير متزامنة مثلما فعلنا في هذا الدرس. للدراسة العميقة، جرب بناء تطبيق يستخدم هذه الـ APIs لممارسة التقنيات التي تعلمتها هنا.
Source:
https://www.digitalocean.com/community/tutorials/how-to-write-asynchronous-code-in-node-js