مقدمة
إحدى الميزات القوية التي تجعل لغة 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 في أدوات مطوّري البرامج.
تخيل أنك د. من وتحتاج إلى القليل من المساعدة في مقارنة الساعة من قبل وصولك إلى تارديس بـ "الآن". من وحدة تحكّم أدوات مطوّري البرامج، يمكنك بسهولة تقييم القيم من خلال نقاط تنفيذ مختلفة وتخزينها وإجراء عمليات حسابية بشأنها.
إنّ البقاء ضمن أدوات مطوّري البرامج للتحكّم في التعبيرات سيوفّر لك الوقت بدلاً من الرجوع إلى رمز المصدر وإجراء التعديلات وإعادة تحميل المتصفّح.
ابتكار الحلول المستندة إلى الوعود المتعددة
إذا كنت تعتقد أنه من الصعب كشف تدفق Gmail التجريبي السابق بدون تفعيل ميزة تكديس المكالمات غير المتزامنة، فهل يمكنك أن تتخيل مدى صعوبة الأمر مع التدفقات غير المتزامنة الأكثر تعقيدًا مثل الوعود التسلسلية؟ دعنا نعيد النظر في المثال الأخير لبرنامج "جيك أرتشيبالد" التعليمي حول وعود JavaScript.
إليك صورة متحركة بسيطة للتنقل بين حزم المكالمات في مثال async-best-example.html من "جيك".
احصل على إحصاءات حول الصور المتحركة على الويب
دعنا نتعمق أكثر في أرشيفات HTML5Rocks. هل تذكرون "بول لويس" Leaner, Meaner, Faster Animations with requestAnimationFrame؟
افتح العرض التوضيحي لـ requestAnimationFrame وإضافة نقطة إيقاف في بداية طريقة update() (حوالي السطر 874) في post.html. باستخدام حزم المكالمات غير المتزامنة، نحصل على مزيد من الإحصاءات حول requestAnimationFrame، بما في ذلك إمكانية الرجوع إلى عملية معاودة الاتصال بحدث الانتقال للأعلى أو للأسفل.
تعقب تحديثات DOM عند استخدام MutationMonitorer
تسمح لنا MutationObserver
بملاحظة التغييرات في نموذج العناصر في المستند (DOM). في هذا المثال البسيط،
عند النقر على الزرّ، يتم إلحاق عقدة DOM جديدة بـ <div class="rows"></div>
.
أضِف نقطة إيقاف داخل nodeAdded()
(السطر 31) في Demo.html. مع تفعيل "حِزم المكالمات غير المتزامنة"، يمكنك الآن توجيه حزمة المكالمات مرة أخرى خلال addNode()
إلى
حدث النقرة الأولى.
نصائح لتصحيح أخطاء JavaScript في حِزم المكالمات غير المتزامنة
تسمية الدوال
إذا كنت تميل إلى تعيين جميع عمليات الاستدعاء كدوال مجهولة المصدر، يمكنك بدلاً من ذلك اختيار اسم لها لتسهيل عرض حزم المكالمات.
على سبيل المثال، خذ دالة مجهولة مثل هذه:
window.addEventListener('load', function() {
// do something
});
وامنحه اسمًا مثل windowLoaded()
:
window.addEventListener('load', function <strong>windowLoaded</strong>(){
// do something
});
عند تنشيط حدث التحميل، سيظهر في تتبُّع تسلسل استدعاء الدوال البرمجية في أدوات مطوّري البرامج مع اسم الدالة بدلاً من الكلمة الغامضة "(دالة مجهولة)". ويسهّل ذلك عليك الاطّلاع بنظرة سريعة على ما يحدث في تقرير تتبُّع تسلسل استدعاء الدوال البرمجية.
استكشاف المزيد
باختصار، هذه هي جميع عمليات الاستدعاء غير المتزامنة التي ستعرض فيها أدوات مطوّري البرامج حزمة المكالمات الكاملة:
- الموقّتات:
يمكنك الرجوع إلى المكان الذي تم فيه إعداد
setTimeout()
أوsetInterval()
. - XHR:
يمكنك الرجوع إلى حيث تم استدعاء
xhr.send()
. - إطارات الصور المتحركة:
يمكنك الرجوع إلى حيث تمت استدعاء
requestAnimationFrame
. - الوعود: عليك العودة إلى المكان الذي حققنا فيه الوعود.
- Object.observe: الرجوع إلى حيث تم ربط معاودة الاتصال بالمراقب في الأصل.
- MutationObservers: عُد إلى المكان الذي تم فيه إطلاق حدث مراقب الطفرة.
- window.postMessage(): تعرّف على مزيد من المعلومات حول مكالمات المراسلة داخل العمليات.
- DataTransferItem.getAsString()
- واجهة برمجة التطبيقات FileSystem
- IndexedDB
- WebSQL
- أحداث DOM المؤهَّلة عبر
addEventListener()
: يمكنك الرجوع إلى المكان الذي بدأ فيه الحدث. لأسباب تتعلق بالأداء، ليست كل أحداث DOM مؤهلة لميزة تكديس الاستدعاءات غير المتزامنة. ومن أمثلة الأحداث المتاحة حاليًا: "التمرير" و"تغيير التجزئة" و"الاختيار". - فعاليات الوسائط المتعددة عبر
addEventListener()
: يمكنك الرجوع إلى المكان الذي بدأت فيه الفعالية. تشمل أحداث الوسائط المتعددة المتاحة ما يلي: أحداث الصوت والفيديو (مثل أحداث 'play' و'pause' و'ratechange') وأحداث WebRTC MediaStreamTrackList (مثل 'addtrack' و'removetrack') وأحداث MediaSource (مثل 'sourceopen').
يجب أن تكون قادرًا على رؤية تتبع تسلسل استدعاء الدوال البرمجية بالكامل لاستدعاءات JavaScript، بحيث لا تكون هذه الشعرة ظاهرة على رأسك. يمكن الاستفادة من هذه الميزة في أدوات مطوري البرامج بشكل خاص عند وقوع أحداث متعددة غير متزامنة في ما يتعلق ببعضها، أو في حال طرح استثناء غير مرصود من داخل استدعاء غير متزامن.
يمكنك تجربتها في Chrome. إذا كانت لديك أي ملاحظات حول هذه الميزة الجديدة، يُرجى مراسلتنا على أداة تتبُّع الأخطاء في "أدوات مطوري البرامج في Chrome" أو في مجموعة "أدوات مطوري البرامج في Chrome".