اشکال زدایی جاوا اسکریپت ناهمزمان با ابزارهای توسعه دهنده کروم

مقدمه

یکی از ویژگی‌های قدرتمندی که جاوا اسکریپت را منحصر به فرد می‌کند، توانایی آن برای کار ناهمزمان از طریق توابع پاسخ به تماس است. تخصیص تماس‌های غیرهمگام به شما امکان می‌دهد کدهای رویداد محور بنویسید، اما ردیابی باگ‌ها را نیز به یک تجربه کوتاه کردن مو تبدیل می‌کند، زیرا جاوا اسکریپت به صورت خطی اجرا نمی‌شود.

خوشبختانه، اکنون در Chrome DevTools، می‌توانید پشته تماس کامل تماس‌های غیرهمزمان جاوا اسکریپت را مشاهده کنید!

نمای کلی تیزر سریع پشته‌های تماس ناهمگام.
نمای کلی تیزر سریع پشته‌های تماس ناهمگام. (به زودی جریان این دمو را بررسی خواهیم کرد.)

هنگامی که ویژگی پشته تماس غیر همگام در DevTools را فعال کردید، می‌توانید وضعیت برنامه وب خود را در مقاطع مختلف زمانی بررسی کنید. برای برخی شنوندگان رویداد، setInterval ، setTimeout ، XMLHttpRequest ، وعده‌ها، requestAnimationFrame ، MutationObservers و موارد دیگر، ردیابی کامل پشته را دنبال کنید.

همانطور که در ردیابی پشته قدم می گذارید، همچنین می توانید مقدار هر متغیری را در آن نقطه خاص از اجرای زمان اجرا تجزیه و تحلیل کنید. این مانند یک ماشین زمان برای عبارات ساعت شماست!

بیایید این ویژگی را فعال کنیم و به چند مورد از این سناریوها نگاهی بیندازیم.

اشکال زدایی ناهمگام را در کروم فعال کنید

با فعال کردن آن در کروم، این ویژگی جدید را امتحان کنید. به پنل Sources Chrome Canary DevTools بروید.

در کنار پانل Call Stack در سمت راست، یک چک باکس جدید برای "Async" وجود دارد. برای روشن یا خاموش کردن اشکال‌زدایی ناهمگام، کادر تأیید را تغییر دهید. (اگرچه پس از روشن شدن، ممکن است هرگز نخواهید آن را خاموش کنید.)

ویژگی همگام سازی را روشن یا خاموش کنید.

رویدادهای تایمر تاخیری و پاسخ های XHR را ضبط کنید

احتمالاً قبلاً این را در جیمیل دیده اید:

جیمیل در حال تلاش مجدد برای ارسال ایمیل است.

اگر مشکلی در ارسال درخواست وجود داشته باشد (یا سرور مشکل دارد یا مشکلات اتصال شبکه در سمت سرویس گیرنده وجود دارد)، Gmail به طور خودکار پس از مدت زمانی کوتاه، پیام را دوباره ارسال می کند.

برای اینکه ببینم چگونه پشته‌های تماس ناهمگام می‌توانند به ما در تجزیه و تحلیل رویدادهای تایمر تأخیری و پاسخ‌های XHR کمک کنند، این جریان را با یک مثال ساختگی Gmail بازسازی کردم. کد کامل جاوا اسکریپت را می توان در لینک بالا پیدا کرد اما جریان به شرح زیر است:

نمودار جریان نمونه ساختگی Gmail.
در نمودار بالا، روش‌هایی که با رنگ آبی مشخص شده‌اند، نقاط اصلی برای این ویژگی جدید DevTool هستند که سودمندترین آنها هستند، زیرا این روش‌ها به صورت ناهمزمان کار می‌کنند.

تنها با نگاه کردن به پنل Call Stack در نسخه‌های قبلی DevTools، یک نقطه شکست در postOnFail() اطلاعات کمی در مورد اینکه postOnFail() از کجا فراخوانی شده است به شما می‌دهد. اما هنگام روشن کردن پشته های ناهمگام به تفاوت نگاه کنید:

قبل از
نقطه انفصال در نمونه ساختگی Gmail بدون پشته تماس ناهمگام تنظیم شده است.
پانل پشته تماس بدون همگام سازی فعال است.

در اینجا می توانید ببینید که postOnFail() از یک فراخوانی AJAX آغاز شده است اما اطلاعات بیشتری وجود ندارد.

بعد از
نقطه انفصال در نمونه ساختگی Gmail با پشته های تماس ناهمگام تنظیم شده است.
پانل پشته تماس با غیر همگام‌سازی فعال است.

در اینجا می توانید ببینید که XHR از submitHandler() آغاز شده است. خوب!

با روشن بودن پشته های تماس async، می توانید کل پشته تماس را مشاهده کنید تا به راحتی ببینید که آیا درخواست از submitHandler() (که پس از کلیک کردن روی دکمه ارسال اتفاق می افتد) یا از retrySubmit() (که پس از تأخیر setTimeout() انجام می شود، شروع شده است. :

submitHandler()
نقطه انفصال در نمونه ساختگی Gmail با پشته های تماس ناهمگام تنظیم شده است
retrySubmit()
نقطه انفصال دیگری در نمونه ساختگی Gmail با پشته های تماس ناهمگام تنظیم شده است

عبارات را به صورت ناهمزمان تماشا کنید

وقتی تمام پشته تماس را طی می‌کنید، عبارات تماشای شما نیز به‌روزرسانی می‌شوند تا وضعیتی را که در آن زمان در آن بود منعکس کنند!

نمونه ای از استفاده از عبارات ساعت با پشته های تماس aysnc

کد را از محدوده های گذشته ارزیابی کنید

علاوه بر تماشای عبارات ساده، می‌توانید با کدهای خود از حوزه‌های قبلی درست در پنل کنسول DevTools JavaScript تعامل داشته باشید.

تصور کنید که شما دکتر Who هستید و برای مقایسه ساعت قبل از ورود به تاردیس با "اکنون" به کمک کمی نیاز دارید. از کنسول DevTools، می توانید به راحتی مقادیر را از نقاط مختلف اجرا ارزیابی، ذخیره و محاسبات انجام دهید.

نمونه ای از استفاده از کنسول جاوا اسکریپت با پشته های تماس aysnc.
از کنسول جاوا اسکریپت در ارتباط با پشته های تماس غیرهمگام برای اشکال زدایی کد خود استفاده کنید. نسخه ی نمایشی بالا را می توانید در اینجا پیدا کنید.

ماندن در DevTools برای دستکاری عبارات خود، زمان شما را از بازگشت به کد منبع، ویرایش و بازخوانی مرورگر صرفه‌جویی می‌کند.

قطعنامه های زنجیره ای وعده را باز کنید

اگر فکر می‌کردید بدون فعال کردن ویژگی پشته تماس همگام‌سازی، باز کردن جریان ساختگی قبلی Gmail دشوار است، آیا می‌توانید تصور کنید که با جریان‌های ناهمزمان پیچیده‌تر مانند وعده‌های زنجیره‌ای چقدر سخت‌تر می‌شود؟ بیایید نمونه نهایی آموزش جیک آرچیبالد در مورد وعده های جاوا اسکریپت را دوباره مرور کنیم.

در اینجا یک انیمیشن کوچک از راه رفتن پشته های تماس در مثال async-best-example.html جیک آورده شده است.

قبل از
نقطه شکست در نمونه وعده‌ها بدون پشته‌های تماس ناهمگام تنظیم شده است
پانل پشته تماس بدون همگام سازی فعال است.

توجه داشته باشید که چگونه پانل Call Stack هنگام تلاش برای اشکال زدایی وعده ها، اطلاعات بسیار کمی دارد.

بعد از
نقطه شکست در نمونه وعده‌ها با پشته‌های تماس ناهمگام تنظیم شده است.
پانل پشته تماس با غیر همگام‌سازی فعال است.

عجب! چنین وعده هایی تماس های زیادی

در مورد انیمیشن های وب خود اطلاعاتی کسب کنید

بیایید عمیق تر به آرشیو HTML5Rocks برویم. انیمیشن های Leaner, Meaner, Faster Paul Lewis با requestAnimationFrame را به خاطر دارید؟

نسخه ی نمایشی requestAnimationFrame را باز کنید و در ابتدای متد update() (حدود خط 874) post.html یک نقطه شکست اضافه کنید. با پشته‌های تماس غیرهمگام، بینش‌های بسیار بیشتری در مورد requestAnimationFrame دریافت می‌کنیم، از جمله توانایی راه رفتن تا بازگشت به تماس اولیه رویداد پیمایش.

قبل از
نقطه انفصال در مثال requestAnimationFrame بدون پشته های تماس ناهمگام تنظیم شده است.
پانل پشته تماس بدون همگام سازی فعال است.
بعد از
نقطه انفصال در مثال requestAnimationFrame با پشته های تماس ناهمگام تنظیم شده است
و با فعال کردن async.

هنگام استفاده از MutationObserver به روز رسانی های DOM را ردیابی کنید

MutationObserver به ما اجازه می دهد تا تغییرات را در DOM مشاهده کنیم. در این مثال ساده ، وقتی روی دکمه کلیک می‌کنید، یک گره DOM جدید به <div class="rows"></div> اضافه می‌شود.

یک نقطه شکست در nodeAdded() (خط 31) در demo.html اضافه کنید. با فعال بودن پشته های تماس async، اکنون می توانید پشته تماس را از طریق addNode() به رویداد کلیک اولیه بازگردانید.

قبل از
نقطه انفصال در مثال mutationObserver بدون پشته تماس ناهمگام تنظیم شده است.
پانل پشته تماس بدون همگام سازی فعال است.
بعد از
نقطه انفصال در مثال mutationObserver با پشته های تماس ناهمگام تنظیم شده است.
و با فعال کردن async.

نکاتی برای اشکال زدایی جاوا اسکریپت در پشته های تماس ناهمگام

توابع خود را نام ببرید

اگر تمایل دارید همه تماس های خود را به عنوان عملکردهای ناشناس اختصاص دهید، ممکن است بخواهید به جای آن نامی برای مشاهده پشته تماس به آنها بدهید.

به عنوان مثال، یک تابع ناشناس مانند زیر بگیرید:

window.addEventListener('load', function() {
  // do something
});

و نامی مانند windowLoaded() به آن بدهید:

window.addEventListener('load', function <strong>windowLoaded</strong>(){
  // do something
});

هنگامی که رویداد بارگذاری فعال می شود، به جای رمز رمزی " (عملکرد ناشناس) " در ردیابی پشته DevTools با نام تابع خود نشان داده می شود. این باعث می شود که در یک نگاه ببینید چه اتفاقی در ردیابی پشته شما می افتد بسیار آسان تر می شود.

قبل از
یک تابع ناشناس
بعد از
یک تابع با نام

بیشتر کاوش کنید

برای جمع بندی، اینها همه تماس های ناهمزمان هستند که DevTools پشته تماس کامل را نمایش می دهد:

  • تایمرها : به جایی که setTimeout() یا setInterval() مقداردهی شده بود برگردید.
  • XHRs : به جایی که xhr.send() فراخوانی شده بود برگردید.
  • قاب های انیمیشن : به جایی که requestAnimationFrame فراخوانی شده است، برگردید.
  • وعده ها : به جایی برگردید که یک وعده حل شده است.
  • Object.observe : به جایی برگردید که پاسخ تماس ناظر در ابتدا محدود شده بود.
  • MutationObservers : به جایی برگردید که رویداد ناظر جهش فعال شد.
  • window.postMessage() : از تماس‌های پیام‌رسانی درون فرآیندی عبور کنید.
  • DataTransferItem.getAsString()
  • FileSystem API
  • IndexedDB
  • WebSQL
  • رویدادهای DOM واجد شرایط از طریق addEventListener() : برگردید به جایی که رویداد فعال شده است. به دلایل عملکرد، همه رویدادهای DOM برای ویژگی پشته تماس غیر همگام‌سازی واجد شرایط نیستند. نمونه هایی از رویدادهای موجود در حال حاضر عبارتند از: 'scroll'، 'hashchange' و 'selectionchange'.
  • رویدادهای چندرسانه‌ای از طریق addEventListener() : به جایی که رویداد اجرا شده است، برگردید. رویدادهای چندرسانه‌ای موجود عبارتند از: رویدادهای صوتی و تصویری (به‌عنوان مثال «پخش»، «مکث»، «ratechange»)، رویدادهای WebRTC MediaStreamTrackList (مانند «addtrack»، «removetrack»)، و رویدادهای MediaSource (مثلاً «sourceopen»).

اینکه بتوانید تمام ردیابی پشته‌های تماس‌های جاوا اسکریپت خود را ببینید باید این موها را روی سرتان نگه دارید. این ویژگی در DevTools به ویژه زمانی مفید خواهد بود که چندین رویداد ناهمگام در رابطه با یکدیگر اتفاق بیفتند، یا اگر یک استثنا غیرقابل کشف از داخل یک تماس برگشتی ناهمگام پرتاب شود.

آن را در کروم امتحان کنید. اگر بازخوردی در مورد این ویژگی جدید دارید، خطی را در ردیاب اشکال Chrome DevTools یا در گروه Chrome DevTools ارسال کنید.