مقدمة
الوعود في جافاسكريبت يمكن أن تكون صعبة الفهم. لذا أود كتابة الطريقة التي أفهم بها الوعود.
فهم الوعود
باختصار، الوعد:
“تخيل أنك طفل. أمك تعدك أنها ستشتري لك هاتف جديد الأسبوع القادم.”
أنت لا تعرف إن كنت ستحصل على ذلك الهاتف حتى الأسبوع القادم. قد تشتري لك أمك فعلاً هاتفاً جديداً، أو لا تفعل.
ذلك هو الوعد. الوعد له ثلاث حالات. وهي:
- معلقة: أنت لا تعرف إن كنت ستحصل على ذلك الهاتف
- مكتملة: الأم سعيدة، تشتري لك هاتفاً جديداً
- مرفوضة: الأم حزينة، لا تشتري لك هاتفاً
إنشاء وعد
لنحول هذا إلى جافاسكريبت.
الكود واضح جداً بحد ذاته.
إليك كيف تبدو بنية Promise عادة:
استهلاك الPromises
الآن بعد أن حصلنا على الPromise، فلنستهلكه:
فلنقم بتشغيل المثال ونرى النتيجة!
عرض: https://jsbin.com/nifocu/1/edit?js,console
سلسلة الوعود
الوعود قابلة للسلسلة.
لنفترض أنك، كطفل، توعد صديقك بأنك ستعرض عليهم الهاتف الجديد عندما تشتريك والدتك واحدًا.
هذه وعدة أخرى. لنكتبها!
ملاحظة: يمكننا تقصير الكود أعلاه بكتابته على النحو التالي:
لنسلسل الوعود. أنت، كطفل، يمكنك فقط بدء وعد showOff
بعد وعد willIGetNewPhone
.
هكذا يمكنك سلسلة الوعد.
الوعود غير متزامنة
الوعود غير متزامنة. لنسجل رسالة قبل وبعد استدعاء الوعد.
ما هي التسلسل المتوقع للإخراج؟ قد تتوقع:
1. before asking Mom
2. Hey friend, I have a new black Samsung phone.
3. after asking mom
ومع ذلك، فإن التسلسل الفعلي للإخراج هو:
1. before asking Mom
2. after asking mom
3. Hey friend, I have a new black Samsung phone.
لن تتوقف عن اللعب أثناء انتظار وعد والدتك (الهاتف الجديد). هذا ما نسميه غير متزامن: سيتم تنفيذ الكود دون حظر أو انتظار النتيجة. أي شيء يحتاج إلى انتظار الوعد للمتابعة يُضاف إلى .then
.
هنا مثال كامل باستخدام ES5:
الوعود في ES5، ES6/2015، ES7/Next
ES5 – أغلب المتصفحات
تعمل الشيء المعروف في بيئات ES5 (جميع المتصفحات الرئيسية + NodeJs) إذا اشتركت في Bluebird مكتبة الوعود. لأن ES5 لا يدعم الوعود بشكل مباشر. وتوجد مكتبة وعد شهيرة أخرى تدعمه Q من قبل Kris Kowal.
ES6 / ES2015 – المتصفحات الحديثة، NodeJs v6
الكود التوضيحي يعمل مباشرة لأن ES6 يدعم الوعود بشكل أصلي. بالإضافة إلى ذلك، مع وظائف ES6، يمكننا تبسيط الكود أكثر باستخدام دالة السهم واستخدام const
و let
.
هنا مثال كامل بكود ES6:
لاحظ أن جميع var
تم استبدالها بـ const
. كل function(resolve, reject)
تم تبسيطها إلى (resolve, reject) =>
. هناك العديد من الفوائد التي تأتي مع هذه التغييرات.
ES7 – Async/Await
أدخل ES7 بناء الجملة async
و await
. يجعل هذا البناء الجملة الغير متزامن أسهل في الفهم، دون الحاجة إلى .then
و .catch
.
أعد كتابة مثالنا باستخدام بناء الجملة ES7:
الوعود ومتى يتم استخدامها
لماذا نحتاج إلى الوعود؟ كيف كان العالم يبدو قبل الوعود؟ قبل الإجابة على هذه الأسئلة، دعونا نعود إلى الأساسيات.
الدالة العادية مقابل الدالة الغير متزامنة
دعونا نلقي نظرة على هذين المثالين. كلا المثالين يقوم بجمع رقمين: أحدهما يجمع باستخدام الدوال العادية، والآخر يجمع عن بُعد.
الدالة العادية لجمع رقمين
الدالة الغير متزامنة لجمع رقمين
إذا قمت بجمع الأرقام باستخدام الدالة العادية، تحصل على النتيجة على الفور. ولكن، عندما تقوم باستدعاء عن بُعد للحصول على النتيجة، تحتاج إلى الانتظار، ولا يمكنك الحصول على النتيجة على الفور.
لا تعرف إن كنت ستحصل على النتيجة لأن الخادم قد يكون متوقفًا، أو بطيئًا في الرد، إلخ. لا تريد أن يتوقف عمليتك بأكملها أثناء انتظار النتيجة.
استدعاء واجهات برمجة التطبيقات، تنزيل الملفات، وقراءة الملفات هي بعض من العمليات الغير متزامنة التي ستقوم بها.
لا تحتاج إلى استخدام الوعود لمكالمة غير متزامنة. قبل الوعود، كنا نستخدم الدوال الاستدعاء. الدوال الاستدعاء هي الدالة التي تستدعيها عندما تحصل على النتيجة المرجعة. لنعدل المثال السابق ليقبل دالة استدعاء.
العملية الغير متزامنة اللاحقة
بدلاً من إضافة الأرقام واحدة تلو الأخرى، نريد إضافة ثلاث مرات. في دالة عادية، سنفعل هذا:-
هذا هو شكل الأمر مع الاستدعاءات الرجعية:
عرض توضيحي: https://jsbin.com/barimo/edit?html,js,console
هذه الصيغة أقل سهولة في الاستخدام بسبب الاستدعاءات الرجعية المتداخلة بعمق.
تجنب الاستدعاءات الرجعية المتداخلة بعمق
يمكن أن تساعدك الوعود على تجنب الاستدعاءات الرجعية المتداخلة بعمق. دعونا نلقي نظرة على نسخة الوعد من نفس المثال:
مع الوعود، نُسطّح الاستدعاء مع .then
. بطريقة ما، يبدو أنظف لأنه لا يوجد تداخل للاستدعاءات. مع بناء جملة ES7 async
، يمكنك تحسين هذا المثال أكثر.
المُلاحظات القابلة للمراقبة
قبل أن تستقر مع الوعود، هناك شيء جديد ظهر لمساعدتك في التعامل مع البيانات الغير متزامنة تسمى المُلاحظات القابلة للمراقبة
.
دعونا نلقي نظرة على نفس العرض التوضيحي مكتوب باستخدام المُلاحظات القابلة للمراقبة. في هذا المثال، سنستخدم RxJS للمُلاحظات القابلة للمراقبة.
يمكن للمُلاحظات القابلة للمراقبة أن تفعل أشياء أكثر إثارة للاهتمام. على سبيل المثال، delay
إضافة الوظيفة بـ 3 ثوانٍ
بسطر واحد فقط أو المحاولة مرة أخرى حتى تتمكن من إعادة استدعاء معين عدد من المرات.
قد تقرأ أحد مقالاتي حول RxJs هنا.
خاتمة
إتقان الدوال الاستدعائية والوعود مهم. افهمهم واستخدمهم. لا داعي للقلق بشأن المراقبين حتى الآن. يمكن أن تلعب جميع الثلاثة دورًا في تطويرك حسب الحالة.
Source:
https://www.digitalocean.com/community/tutorials/understanding-javascript-promises