تنفيذ المتزامن وينتظر مع المولدات

الصورة بليك كونالي على Unsplash

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

اتضح أن الأمر بسيط للغاية ، حيث يمكن بسهولة محاكاة سلوك المتزامن والانتظار باستخدام المولدات. لنلقي نظرة!

المضي قدما ، استنساخ مستودع ودعونا نبدأ.

مولدات كهرباء

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

المولدات هي كائنات تم إنشاؤها بواسطة وظائف المولد - وظائف مع * (علامة نجمية) بجوار اسمهم.

تتمتع هذه المولدات بقدرة مذهلة تتيح لنا إيقاف تنفيذ الشفرة - متى أردنا - باستخدام عائد الكلمات الرئيسية.

النظر في هذا المثال:

مولد const = (وظيفة * () {
  // في انتظار .next ()
  const أ = العائد 5 ؛
  // في انتظار .next ()
  console.log (أ)؛ // => 15
}) ()؛

console.log (generator.next ())؛ // => {done: false ، القيمة: 5}
console.log (generator.next (15))؛ // => {done: true ، value: undefined}

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

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

انتظر ، انتظر لحظة

ألم تتسائل يومًا من أي وقت مضى كيف تعمل الأمور حقًا؟

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

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

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

ما يجب أن تفعله وظيفة asynq لدينا:

  • انتظر رمز غير متزامن قبل متابعة التنفيذ
  • إرجاع وعد مع القيمة التي تم إرجاعها من الدالة
  • جعل محاولة / الصيد العمل على رمز غير متزامن

ملاحظة: لأننا نستخدم المولدات الكهربائية ، فإن انتظارنا يصبح عائدًا.

حسنا ، عظيم! الآن يمكننا التحدث عن التنفيذ.

تأخذ دالة asynq الخاصة بنا كمولد دالة - من خلال استدعاء ذلك ، نقوم بإنشاء مولد.

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

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

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

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

عندما يتم إنشاء المولد ، فإننا نرجع قيمة الإرجاع للمولد في وعد.

الآن ، وبعد إجراء اختباراتنا ، يمكننا أن نرى أن كل شيء يعمل كما هو متوقع.

تغليف

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

لا تتردد في الذهاب أكثر من رمز. كلما كان فهمك للأفكار الأساسية أفضل ، زادت قدرتك على تقدير بريق المبدعين في المزامنة وانتظار الكلمات الرئيسية.

شكرا جزيلا على القراءة لك! أتمنى أن تكون قد وجدت هذه المقالة مفيدة. آمل أيضًا أن يساعدك ذلك في رؤية أنه لا يوجد سحر في المزامنة وينتظر الكلمات الرئيسية ، ويمكن استبدالها بسهولة بمولدات.

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

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

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

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