تنفيذ الوعود في جافا سكريبت

الصورة من قبل جوشوا ستانارد على Unsplash

أكثر ما أحبه في البرمجة هو الآها! لحظة عندما تبدأ في فهم مفهوم بالكامل. على الرغم من أن الأمر قد يستغرق وقتًا طويلاً دون بذل جهد كبير للوصول إلى هناك ، إلا أنه بالتأكيد يستحق كل هذا العناء.

أعتقد أن الطريقة الأكثر فاعلية لتقييم (والمساعدة في تحسين) درجة فهمنا لموضوع معين هي محاولة تطبيق المعرفة على العالم الحقيقي. هذا لا يتيح لنا فقط تحديد نقاط الضعف لدينا ومعالجتها في النهاية ، ولكن يمكن أيضًا إلقاء بعض الضوء على طريقة عمل الأشياء. غالبًا ما يكشف نهج التجربة والخطأ البسيط عن تلك التفاصيل التي ظلت بعيدة المنال سابقًا.

مع وضع ذلك في الاعتبار ، أعتقد أن تعلم كيفية تنفيذ الوعود كان أحد أهم اللحظات في رحلة البرمجة الخاصة بي - لقد أعطاني نظرة ثاقبة لا تقدر بثمن حول كيفية عمل الشفرة غير المتزامنة وجعلني أفضل مبرمجًا بشكل عام.

آمل أن يساعدك هذا المقال في تحقيق الوعود بتنفيذ جافا سكريبت أيضًا.

يجب أن نركز على كيفية تنفيذ جوهر الوعد وفقًا لمواصفات Promises / A + مع بعض الأساليب في Bluebird API. سنستخدم أيضًا أسلوب TDD مع Jest.

سيكون برنامج TypeScript مفيدًا أيضًا.

بالنظر إلى أننا سنعمل على مهارات التنفيذ هنا ، سأفترض أن لديك بعض الفهم الأساسي لماهية الوعود والشعور الغامض بكيفية عملها. إذا لم تفعل ، فهناك مكان رائع للبدء.

والآن بعد أن خرجنا عن هذا الطريق ، تابعنا واستنسخ المستودع ودعنا نبدأ.

جوهر الوعد

كما تعلمون ، الوعد هو كائن ذو الخصائص التالية:

ثم

طريقة تربط المعالج بوعدنا. إنها تُرجع وعدًا جديدًا بقيمة القيمة السابقة المعينة بواسطة إحدى طرق المعالج.

معالجات

مجموعة من معالجات المرفقة بحلول ذلك الوقت. المعالج هو كائن يحتوي على طريقتين onSuccess و onFail ، وكلاهما يتم تمريرهما كوسيطتين إلى ذلك الحين (onSuccess ، onFail).

حالة

يمكن أن يكون الوعد في واحدة من ثلاث ولايات: تم حلها أو رفضها أو تعليقها.

يعني حل إما أن كل شيء سار بسلاسة وتلقينا قيمة لدينا ، أو وقعنا في الخطأ والتعامل معها.

الرفض يعني إما أننا رفضنا الوعد أو تم إلقاء خطأ ولم نلتزم به.

معلق يعني أنه لم يتم استدعاء حل أو طريقة الرفض حتى الآن وما زلنا ننتظر القيمة.

يعني مصطلح "الوعد الذي تم تسويته" أن الوعد إما حل أو رفض.

القيمة

القيمة التي قمنا بحلها أو رفضها.

بمجرد تعيين القيمة ، لا توجد طريقة لتغييرها.

اختبارات

وفقًا لنهج TDD ، نريد أن نكتب اختباراتنا قبل ظهور الشفرة الفعلية ، لذلك دعونا نفعل ذلك تمامًا.

فيما يلي اختبارات لبنا:

تشغيل اختباراتنا

أوصي بشدة باستخدام ملحق Jest لـ Visual Studio Code. إنه يدير اختباراتنا في الخلفية بالنسبة لنا ويظهر لنا النتيجة مباشرة بين سطور الكود الخاص بنا كنقاط خضراء وحمراء للاختبارات التي تم اجتيازها وفشلها ، على التوالي.

لمشاهدة النتائج ، افتح وحدة التحكم "الإخراج" واختر علامة التبويب "Jest".

يمكننا أيضًا إجراء اختباراتنا من خلال تنفيذ الأمر التالي:

اختبار تشغيل npm

بغض النظر عن الطريقة التي نجري بها الاختبارات ، يمكننا أن نرى أن جميعها تعود سلبية.

لنغير ذلك.

تنفيذ الوعد الأساسية

البناء

لدينا منشئ يأخذ رد الاتصال كمعلمة.

نحن ندعو هذا رد الاتصال مع this.resolve و this.reject كوسائط.

لاحظ أننا عادةً ما كنا سنربط هذا.حل و this.reject إلى هذا ، ولكن هنا استخدمنا طريقة سهم الفئة بدلاً من ذلك.

setResult

الآن علينا أن نضع النتيجة. يرجى تذكر أنه يجب علينا التعامل مع النتيجة بشكل صحيح ، مما يعني أنه في حالة إرجاع وعد ، يجب علينا حلها أولاً.

أولاً ، نتحقق مما إذا كانت الدولة ليست معلقة - إذا كانت كذلك ، فإن الوعد قد تم تسويته بالفعل ولا يمكننا تخصيص أي قيمة جديدة له.

ثم نحتاج إلى التحقق مما إذا كانت القيمة قابلة للتطبيق. وبكل بساطة ، فإن الأكل هو كائن به ثم كطريقة.

بالاتفاق ، يجب أن يتصرف حينها مثل الوعد. حتى نحصل على النتيجة ، سوف ندعو ثم نمرر كحجج this.resolve و this.reject.

بمجرد أن يستقر الحل ، سوف يستدعي أحد أساليبنا ويمنحنا القيمة غير الموعودة المتوقعة.

حتى الآن علينا أن نتحقق مما إذا كان كائن ما هو قابل للإدارة.

من المهم أن ندرك أن وعدنا لن يكون متزامنًا أبدًا ، حتى لو كان الكود الموجود في رد الاتصال.

نحن بصدد تأخير التنفيذ حتى التكرار التالي من حلقة الحدث باستخدام setTimeout.

الآن الشيء الوحيد المتبقي هو تعيين القيمة والحالة الخاصة بنا ثم تنفيذ المعالجات المسجلة.

executeHandlers

مرة أخرى ، تأكد من أن الدولة ليست معلقة.

تملي حالة الوعد الوظيفة التي سنستخدمها.

إذا تم حلها ، فينبغي علينا تنفيذ onSuccess ، وإلا - onFail.

دعنا الآن نقضي على مجموعة معالجاتنا لكي نكون آمنين وليس لتنفيذ أي شيء عن طريق الخطأ في المستقبل. يمكن إرفاق معالج وتنفيذها لاحقًا على أي حال.

وهذا ما يجب أن نناقشه بعد ذلك: طريقة لإرفاق معالجنا.

attachHandler

انها حقا بسيطة كما يبدو. نقوم فقط بإضافة معالج إلى مجموعة معالجات لدينا وتنفيذه. هذا هو.

الآن ، لكي نجمع كل ذلك معًا ، نحتاج إلى تنفيذ الطريقة التي اتبعناها بعد ذلك.

ثم

في ذلك الوقت ، نرجع وعدًا ، وفي رد الاتصال نعلق معالجًا يُستخدم بعد ذلك لانتظار تسوية الوعد الحالي.

عندما يحدث ذلك ، سيتم تنفيذ إما onSuccess أو onFail الخاص بالمدير وسنتابع وفقًا لذلك.

شيء واحد يجب تذكره هنا هو أن أيا من معالجات مرت إلى ذلك الحين هو المطلوب. ومع ذلك ، من المهم ألا نحاول تنفيذ شيء قد يكون غير محدد.

أيضا ، في onFail عندما يتم تمرير المعالج ، نحن في الواقع حل الوعد الذي تم إرجاعه ، لأنه قد تم التعامل مع الخطأ.

قبض على

الصيد هو في الواقع مجرد تجريد على طريقة ثم.

هذا هو.

أخيرا

أخيرًا ، ما هو إلا تجريد من فعل ذلك (أخيرًا ، أخيرًا ، أخيرًا) ، لأنه لا يهتم حقًا بنتيجة الوعد.

في الواقع ، فإنه يحافظ أيضًا على نتيجة الوعد السابق ويعيده. لذا فإن كل ما يتم إرجاعه بواسطة finalCb لا يهم حقًا.

إلى سلسلة

سيعود فقط سلسلة [كائن PQ].

بعد تنفيذ جوهر وعودنا ، يمكننا الآن تنفيذ بعض أساليب Bluebird المذكورة سابقًا ، والتي ستجعل التشغيل على الوعود أسهل بالنسبة لنا.

طرق إضافية

Promise.resolve

كيف ينبغي أن تعمل.

Promise.reject

كيف ينبغي أن تعمل.

Promise.all

كيف ينبغي أن تعمل.

أعتقد أن التنفيذ واضح ومباشر.

بدءًا من collection.length ، نقوم بالعد التنازلي مع كل tryResolve حتى نصل إلى 0 ، مما يعني أنه قد تم حل كل عنصر من عناصر المجموعة. نحن ثم حل المجموعة التي تم إنشاؤها حديثا.

Promise.any

كيف ينبغي أن تعمل.

نحن ببساطة ننتظر القيمة الأولى لحلها وإعادتها في وعد.

Promise.props

كيف ينبغي أن تعمل.

نقوم بالتكرار على مفاتيح الكائن الذي تم تمريره ، مع حل كل قيمة. ثم نخصص القيم للكائن الجديد ونحل الوعد به.

Promise.prototype.spread

كيف ينبغي أن تعمل.

Promise.delay

كيف ينبغي أن تعمل.

باستخدام setTimeout ، نقوم ببساطة بتأخير تنفيذ وظيفة العزم بعدد معين من المللي ثانية.

Promise.prototype.timeout

كيف ينبغي أن تعمل.

هذا هو واحد صعبة بعض الشيء.

إذا تم تنفيذ setTimeout بشكل أسرع من وعدنا ، فسيتم رفض الوعد بخطأ خاص.

Promise.promisify

كيف ينبغي أن تعمل.

نحن نطبق على الدالة جميع الوسائط التي تم تمريرها ، بالإضافة إلى - كأحدث واحد - نحن نقدم رد الاتصال خطأ أولاً.

Promise.promisifyAll

كيف ينبغي أن تعمل.

نقوم بالتكرار على مفاتيح الكائن ونعد طرقه ونضيف إلى كل اسم لكلمة طريقة Async.

تغليف

لم يتم تقديمها هنا سوى عدد قليل من بين جميع أساليب واجهة برمجة تطبيقات Bluebird ، لذلك أنا أشجعك بشدة على استكشاف البقية والتجول معها ومحاولة تنفيذ ما تبقى منها.

قد يبدو الأمر صعبًا في البداية ولكن لا يتم إحباطه - سيكون من غير المجدي إذا كان الأمر سهلاً.

شكرا جزيلا على القراءة لك! آمل أن تكونوا قد وجدتوا هذه المقالة مفيدة وأنك ساعدت في فهم مفهوم الوعود ، وأنك من الآن فصاعدًا ستشعر براحة أكبر في استخدامها أو ببساطة كتابة التعليمات البرمجية غير المتزامنة.

إذا كان لديك أي أسئلة أو تعليقات ، فلا تتردد في وضعها في قسم التعليقات أدناه أو أرسل لي رسالة.

تحقق من وسائل الاعلام الاجتماعية بلدي!

الانضمام إلى النشرة الإخبارية بلدي!

نُشر في الأصل على www.mcieslar.com في 4 أغسطس 2018.