الجحيم رد الاتصال
بالنسبة لمبرمجي JavaScript ، فإن معالجة عمليات الاسترجاعات هي معلقة ، لكن التعامل مع عمليات الاسترجاعات بمستويات عميقة جدًا ليست جميلة. يستخدم مقتطفات رمز العينة التالية عمليات اتصال ثلاثية الطبقات ، ثم تقوم بتجديد الدماغ لمزيد من طبقات المشاهد. إنه ببساطة حامض. هذا هو الجحيم رد الاتصال الأسطوري.
getDireCtories (function (dirs) {getFiles (dirs [0] ، function (files) {getContent (files [0] ، function (file ، content) {console.log ('filename:' ، file) ؛ console.log (content) ؛}) ؛}) ؛ وظيفة getDirectories (رد الاتصال) {setTimeOut (function () {callback (['/home/ben']) ؛} ، 1000) ؛} وظيفة getFiles (dir ، callback) {setTimeOut (function () setTimeOut (function () {callback (file ، 'content') ؛} ، 1000)}حل
هناك العديد من الحلول غير المتزامنة في النظام الإيكولوجي التي يمكنها التعامل مع مشكلة جحيم رد الاتصال ، مثل Bluebird و Q ، وما إلى ذلك. تركز هذه المقالة على دعم البرمجة غير المتزامنة في مواصفات ECMASCRIPT 6/7.
وعد ES6
Promise هو حل للبرمجة غير المتزامنة وأداة قوية لحل مشكلة جحيم رد الاتصال.
تم قبول الوعد بشكل رئيسي في النظام الإيكولوجي JavaScript في عام 2007 عندما أضاف إطار Dojo dojo.deferred وظيفة. مع شعبية dojo.deferred ، في عام 2009 ، اقترح Kris Zyp وعود CommonJS/مواصفات. بعد ذلك ، ظهر عدد كبير من تطبيقات الوعد في النظام الإيكولوجي ، بما في ذلك Q.JS ، FuturesJs ، وما إلى ذلك. بالطبع ، تعود شعبية الوعد إلى حد كبير إلى وجود jQuery ، لكن jQuery لا يمتثل تمامًا للوعود المشتركة/المواصفات. ثم كما ترون ، تشمل مواصفات ES 6 الوعد.
تم وصف الوعد في MDN على النحو التالي:
كائن الوعد هو وكيل لقيمة الإرجاع ، والتي قد لا تكون معروفة عند إنشاء كائن الوعد. يتيح لك تحديد طريقة التعامل للنجاح أو فشل عملية غير متزامنة. هذا يسمح للطريقة غير المتزامنة بإرجاع قيمة مثل طريقة متزامنة: تقوم الطريقة غير المتزامنة بإرجاع قيمة الإرجاع الأصلية
الكود التالي هو مثال في قسم "Callback Hell" الذي تم تنفيذه من خلال الوعد. لا يبدو الرمز موجزًا للغاية ، لكنه تحسن بشكل كبير مقارنةً بالاسترداد التقليدي للتسلسل الهرمي ، والرمز أكثر قابلية للصيانة.
getDirectories (). ثم (الدالة (dirs) {return getFiles (dirs [0]) ؛}). ثم (الوظيفة (الملفات) {return getContent (files [0]) ؛}). وظيفة getDirectories () {return New Promise (function (حل ، رفض) {setTimeOut (function () {desolve (['/home/ben']) ؛} ، 1000) ؛}) ؛ "/test2.txt ']) ؛مولد ES6
إن تنفيذ الوعد ليس بسيطًا بما فيه الكفاية ، لا نزال بحاجة إلى خيار أفضل ، و CO هو أحد الخيارات. CO هي وحدة تحكم تدفق غير متزامنة على أساس المولد. قبل فهم CO ، تحتاج إلى فهم المولد أولاً. يجب أن يفهم الطلاب الذين يعرفون C# أن إصدار C# 2.0 يقدم الكلمة الرئيسية لتكرار المولد. يشبه Generator ES 6 C#، ويستخدم أيضًا سكر بناء الجملة ، ويقوم بتنفيذ آلة الحالة داخليًا. للاستخدام المحدد ، يرجى الرجوع إلى قسم مستند MDN* ، والإشارة إلى مدونة فريق AlloyTeam لفهم المولد المتعمق. استخدم CO للدمج بذكاء ES6 Generator و ES6 وعد بإجراء مكالمات غير متزامنة أكثر انسجاما.
CO (function* () {var dirs = getDirectories () ؛ var files = getFiles العائد (dirs [0]) ؛ var contentval = getContent (files [0]) ؛ console.log ('filename:' ، contentval.file) ؛ console.log (contentval.content) ؛}) ؛CO ذكي للغاية ، ويمكن أن تبسيط رمزها الأساسي المثال التالي. تتمثل الفكرة العامة في استخدام مولد التوقيت المتكرر حتى يتم الانتهاء من الدولة ، بالطبع تقوم شركة CO أكثر.
Rungenerator () ؛ الدالة* run () {var dirs = getDirectories () ؛ ملفات var = getFiles (dirs [0]) ؛ var contentVal = getContent (الملفات [0]) ؛ console.log ('filename:' ، contentval.file) ؛ console.log (contentVal.Content) ؛} وظيفة RunGenerator () {var gen = run () ؛ وظيفة go (النتيجة) {if (result.done) return ؛ result.value.then (function (r) {go (gen.next (r)) ؛}) ؛ } go (gen.next ()) ؛}ES7 Async/في انتظار
Generator ES6 جيد حقًا ، لكن من المؤسف أنني بحاجة إلى دعم مكتبة طرف ثالث. والخبر السار هو أن ES 7 ستقدم الكلمة الرئيسية غير المتزامنة/في انتظار حل مشكلة المكالمات غير المتزامنة تمامًا. حسنًا ، .NET هو خطوة واحدة إلى الأمام ، و .net Framework 4.5 هو بالفعل أول من يدعمه.
سيتم كتابة رمز المستقبل مثل هذا:
Run () ؛ Async Function Run () {var dirs = await getDirectories () ؛ ملفات var = تنتظر getFiles (dirs [0]) ؛ var contentVal = في انتظار getContent (الملفات [0]) ؛ console.log ('filename:' ، contentval.file) ؛ console.log (contentval.content) ؛}ختاماً
من طريقة البرمجة غير المتزامنة الكلاسيكية ، إلى تحسين البرمجة غير المتزامنة من خلال مواصفات الوعد ES6 ، إلى المعالجة الأنيقة للمقسم المشترك مع مولد ES ، وأخيراً النهاية المثالية لبرنامج Async/في انتظار ES7 ، يمكننا أن نفهم سبب وجود هذه الميزات في ECMAS.