مقدمة
من الميزات الفعّالة التي تجعل JavaScript فريدة هي قدرتها على العمل بشكل غير متزامن من خلال دوالّ ردّ الاتصال. يتيح لك تحديد عمليات الاستدعاء غير المتزامنة كتابة رمزبرمجي مستند إلى الأحداث، ولكنه يجعل أيضًا عملية تتبُّع الأخطاء أمرًا شاقًا، لأنّ رمز JavaScript لا يتم تنفيذه بطريقة خطية.
لحسن الحظ، يمكنك الآن في "أدوات مطوري البرامج في Chrome" عرض السلسلة الكاملة لطلبات الاتصال بوظائف الاستدعاء غير المتزامنة لـ JavaScript.
بعد تفعيل ميزة تسلسل المكالمات غير المتزامنة في "أدوات المطوّر"، ستتمكّن من
التوغّل في حالة تطبيق الويب في نقاط زمنية مختلفة. اطّلِع على مسار التتبّع الكامل
للبعض من مستمعي الأحداث وsetInterval
وsetTimeout
وXMLHttpRequest
والوعود وrequestAnimationFrame
وMutationObservers
وغير ذلك.
أثناء التنقّل في تتبع تسلسل استدعاء الدوال البرمجية، يمكنك أيضًا تحليل قيمة أي متغيّر في تلك النقطة المحدّدة من وقت التشغيل. إنّها بمثابة آلة زمنية لتعبيرات الساعة.
لنفعّل هذه الميزة ونلقي نظرة على بعض هذه السيناريوهات.
تفعيل تصحيح الأخطاء غير المتزامنة في Chrome
يمكنك تجربة هذه الميزة الجديدة من خلال تفعيلها في Chrome. انتقِل إلى لوحة المصادر في "أدوات مطوّري البرامج في Chrome Canary".
بجانب لوحة تسلسل استدعاء الدوال البرمجية على يسار الصفحة، يتوفّر مربّع اختيار جديد لـ "غير متزامن". بدِّل مربّع الاختيار لتفعيل ميزة تصحيح الأخطاء غير المتزامنة أو إيقافها. (مع أنّه بعد تفعيلها، قد لا تريد إيقافها مطلقًا).
تسجيل أحداث الموقّت المتأخرة وردود XHR
من المرجّح أنّك رأيت هذا الرمز من قبل في Gmail:
إذا حدثت مشكلة في إرسال الطلب (إما أنّ الخادم يواجه مشاكل أو أنّ هناك مشاكل في الاتصال بالشبكة من جهة العميل)، سيحاول Gmail تلقائيًا إعادة إرسال الرسالة بعد مهلة قصيرة.
لمعرفة كيف يمكن أن تساعدنا تسلسلات المكالمات غير المتزامنة في تحليل أحداث الموقّت المتأخر واستجابات XHR، أعدتُ هذه العملية باستخدام مثال محاكاة على Gmail. يمكن العثور على رمز JavaScript الكامل في الرابط أعلاه، ولكن العملية هي على النحو التالي:
من خلال النظر فقط إلى لوحة "تسلسل استدعاء الدوال البرمجية" في الإصدارات السابقة من "أدوات مطوّري البرامج"، لن يمنحك نقطة التوقف فيpostOnFail()
سوى معلومات قليلة عن مكان استدعاءpostOnFail()
. ولكن اطّلِع على الفرق عند تفعيل
الأداة المتعدّدة المهام غير المتزامنة:
عند تفعيل تسلسلات المكالمات غير المتزامنة، يمكنك عرض تسلسل المكالمات بالكامل لتحديد ما إذا كان الطلب قد بدأ من submitHandler()
(يحدث ذلك بعد النقر على زر الإرسال) أو من
retrySubmit()
(يحدث ذلك بعد تأخير setTimeout()
):
مشاهدة تعبيرات المشاهدة بشكل غير متزامن
عند مراجعة تسلسل استدعاء الدوالّ بالكامل، سيتم أيضًا تعديل التعبيرات التي تمّت مراقبتها لعكس الحالة التي كانت عليها في ذلك الوقت.
تقييم الرمز البرمجي من النطاقات السابقة
بالإضافة إلى مراقبة التعبيرات، يمكنك التفاعل مع الرمز من النطاقات السابقة مباشرةً في لوحة وحدة تحكّم JavaScript في أدوات مطوّري البرامج.
لنفترض أنّك الدكتور "هو" وتحتاج إلى مساعدة صغيرة في مقارنة الساعة من قبل دخولك إلى "تارديس" إلى "الآن". من وحدة تحكّم DevTools، يمكنك بسهولة تقييم القيم وتخزينها وإجراء العمليات الحسابية عليها من نقاط تنفيذ مختلفة.
سيوفّر لك البقاء في "أدوات مطوّري البرامج" لتعديل التعبيرات وقتًا من خلال عدم الحاجة إلى التبديل مرة أخرى إلى رمز المصدر وإجراء التعديلات وتحديث المتصفّح.
حلّ قرارات الوعود المتسلسلة
إذا كنت تعتقد أنّه كان من الصعب حلّ عملية Gmail النموذجية السابقة بدون تفعيل ميزة التسلسل المتزامن لطلبات الاتصال، هل يمكنك تخيل مدى صعوبة حلّها باستخدام عمليات معقدة أكثر من عمليات التسلسل غير المتزامن، مثل الوعود المتسلسلة؟ لنطّلِع مجددًا على المثال الأخير من البرنامج التعليمي الذي أعدّه "جاك أرشيبالد" حول وعود JavaScript.
في ما يلي صورة متحركة صغيرة لعرض تسلسلات استدعاء الدوالّ في مثال async-best-example.html الذي أعدّه "جاك".
الحصول على إحصاءات عن الصور المتحركة على الويب
لنطّلع على المزيد من المعلومات في أرشيف HTML5Rocks. هل تذكر مقالة "بول لويس" بعنوان إنشاء صور متحركة أكثر كفاءةً وسرعةً باستخدام requestAnimationFrame؟
افتح العرض التوضيحي لطلب الرسوم المتحركة وأضِف نقطة توقُّف في بداية الطريقة update() (بالقرب من السطر 874) منملف post.html. باستخدام تسلسلات استدعاءات غير متزامنة، نحصل على المزيد من الإحصاءات حول requestAnimationFrame، بما في ذلك إمكانية التنقّل بالكامل إلى الخلف إلى دالة الاستدعاء لحدث الانتقال إلى أعلى أو أسفل الصفحة.
تتبُّع تعديلات DOM عند استخدام MutationObserver
MutationObserver
تسمح لنا برصد التغييرات في DOM. في هذا المثال البسيط،
عند النقر على الزر، تتم إضافة عقدة DOM جديدة إلى <div class="rows"></div>
.
أضِف نقطة توقف في nodeAdded()
(السطر 31) في demo.html. عند تفعيل توفُّر ملف برمجي دوار لسلسلة معالجة طلبات addNode()
، يمكنك الآن التنقّل في تسلسل استدعاء الدوالّ من خلال addNode()
إلى حدث النقر الأولي.
نصائح لتصحيح أخطاء JavaScript في تسلسلات استدعاء الدوال البرمجية غير المتزامنة
تسمية الدوالّ
إذا كنت تميل إلى تعيين جميع وظائف الاستدعاء كوظائف مجهولة الهوية، قد تحتاج بدلاً من ذلك إلى منحها اسمًا لتسهيل عرض تسلسل استدعاء الدوال البرمجية.
على سبيل المثال، لنأخذ دالة مجهولة الهوية على النحو التالي:
window.addEventListener('load', function() {
// do something
});
وامنحه اسمًا مثل windowLoaded()
:
window.addEventListener('load', function <strong>windowLoaded</strong>(){
// do something
});
عند بدء حدث load، سيظهر في "تتبُّع تسلسل استدعاء الدوال البرمجية" في DevTools مع اسم دالته بدلاً من العبارة المشفّرة "(دالة مجهولة)". يسهّل ذلك معرفة ما يحدث في تتبع تسلسل استدعاء الدوالّ في لمح البصر.
استكشاف المزيد
للتلخيص، في ما يلي جميع عمليات الاستدعاء غير المتزامنة التي ستعرض فيها أدوات المطوّر حزمة استدعاء كاملة:
- الموقّتات:
ارجع إلى حيث تمّت بدء
setTimeout()
أوsetInterval()
. - طلبات البيانات عبر HTTP (XHR):
ارجع إلى المكان الذي تم فيه استدعاء
xhr.send()
. - إطارات الصور المتحركة:
ارجع إلى المكان الذي تم فيه استدعاء
requestAnimationFrame
. - الوعد: يمكنك الرجوع إلى المكان الذي تم فيه حلّ وعد.
- Object.observe: الرجوع إلى المكان الذي تم فيه ربط دالة الاستدعاء للمراقِب في الأصل
- MutationObservers: يمكنك الرجوع إلى المكان الذي تم فيه تنشيط حدث MutationObserver.
- window.postMessage(): تخطّي طلبات المراسلة داخل العملية
- DataTransferItem.getAsString()
- FileSystem API
- IndexedDB
- WebSQL
- أحداث DOM المؤهَّلة من خلال
addEventListener()
: ارجع إلى المكان الذي تم فيه بدء الحدث. لأسباب تتعلّق بالأداء، ليست كل أحداث DOM مؤهّلة لاستخدام ميزة "تجميعات المكالمات غير المتزامنة". تشمل أمثلة الأحداث المتاحة حاليًا ما يلي: "scroll" و"hashchange" و "selectionchange". - أحداث الوسائط المتعددة من خلال
addEventListener()
: ارجع إلى المكان الذي تم فيه بدء الحدث. تشمل أحداث الوسائط المتعددة المتاحة: أحداث الصوت والفيديو (مثل "تشغيل" و"إيقاف مؤقت" و"تغيير السرعة") وأحداث WebRTC MediaStreamTrackList (مثل "إضافة مقطع صوتي" و"إزالة مقطع صوتي") وأحداث MediaSource (مثل "فتح المصدر").
من المفترض أن يساعدك الاطّلاع على تتبع تسلسل استدعاء الدوال البرمجية JavaScript الكامل في حلّ المشكلة. ستكون هذه الميزة في "أدوات المطوّر" مفيدة بشكل خاص عند حدوث أحداث متعدّدة غير متزامنة في ما يتعلّق ببعضها، أو في حال تم طرح استثناء غير محصَّل من داخل دالة استدعاء غير متزامنة.
جرِّب ذلك في Chrome. إذا كانت لديك ملاحظات حول هذه الميزة الجديدة، يُرجى التواصل معنا على أداة تتبُّع الأخطاء في "أدوات مطوّري البرامج في Chrome" أو في مجموعة "أدوات مطوّري البرامج في Chrome".