परिचय
JavaScript को खास बनाने वाली एक अहम सुविधा यह है कि यह कॉलबैक फ़ंक्शन के ज़रिए, एक साथ कई काम कर सकता है. एसिंक्रोनस कॉलबैक असाइन करने से, इवेंट-ड्रिवन कोड लिखा जा सकता है. हालांकि, इससे गड़बड़ियों को ट्रैक करना मुश्किल हो जाता है, क्योंकि JavaScript लीनियर तरीके से काम नहीं कर रहा है.
अच्छी बात यह है कि अब Chrome DevTools में, ऐसिंक्रोनस JavaScript कॉलबैक का पूरा कॉल स्टैक देखा जा सकता है!

DevTools में असाइन किए गए कॉल स्टैक की सुविधा चालू करने के बाद, आपके पास समय के अलग-अलग पलों पर अपने वेब ऐप्लिकेशन की स्थिति के बारे में जानने का विकल्प होगा. कुछ इवेंट लिसनर, setInterval
,setTimeout
, XMLHttpRequest
,
प्रॉमिस, requestAnimationFrame
, MutationObservers
वगैरह के लिए पूरा स्टैक ट्रेस देखें.
स्टैक ट्रेस पर चलते समय, रनटाइम की प्रोसेस के उस खास पॉइंट पर किसी भी वैरिएबल की वैल्यू का विश्लेषण भी किया जा सकता है. यह स्मार्टवॉच पर इस्तेमाल किए जाने वाले एक्सप्रेशन के लिए, टाइम मशीन की तरह है!
आइए, इस सुविधा को चालू करें और इनमें से कुछ स्थितियों पर नज़र डालें.
Chrome में एक साथ काम नहीं करने वाली प्रोसेस को डीबग करने की सुविधा चालू करना
इस नई सुविधा को Chrome में चालू करके आज़माएं. Chrome Canary DevTools के सोर्स पैनल पर जाएं.
दाईं ओर कॉल स्टैक पैनल के बगल में, "असाइनमेंट के साथ-साथ अन्य काम करना" के लिए एक नया चेकबॉक्स है. असाइनमेंट के साथ-साथ डीबग करने की सुविधा को चालू या बंद करने के लिए, चेकबॉक्स को टॉगल करें. हालांकि, इसे चालू करने के बाद, शायद आप इसे कभी बंद न करना चाहें.

देर से होने वाले टाइमर इवेंट और XHR रिस्पॉन्स कैप्चर करना
आपको यह मैसेज, Gmail में पहले भी दिख चुका होगा:

अगर अनुरोध भेजने में कोई समस्या आती है (या तो सर्वर में समस्याएं आ रही हैं या क्लाइंट साइड पर नेटवर्क कनेक्टिविटी से जुड़ी समस्याएं आ रही हैं), तो Gmail कुछ समय के बाद मैसेज को अपने-आप फिर से भेजने की कोशिश करेगा.
हमने Gmail के मॉक उदाहरण की मदद से, उस फ़्लो को फिर से बनाया है, ताकि यह देखा जा सके कि असाइन किए गए कॉल स्टैक, देर से होने वाले टाइमर इवेंट और XHR रिस्पॉन्स का विश्लेषण कैसे कर सकते हैं. ऊपर दिए गए लिंक में, JavaScript का पूरा कोड मिल सकता है. हालांकि, इसका फ़्लो इस तरह है:

DevTools के पिछले वर्शन में, कॉल स्टैक पैनल को सिर्फ़ देखने पर, postOnFail()
में ब्रेकपॉइंट से आपको यह जानकारी नहीं मिलती कि postOnFail()
को कहां से कॉल किया जा रहा है. हालांकि, असाइनमेंट के लिए एक से ज़्यादा स्टैक इस्तेमाल करने की सुविधा चालू करने पर, इस अंतर को देखें:

यहां देखा जा सकता है कि postOnFail()
को AJAX कॉलबैक से शुरू किया गया था, लेकिन कोई और जानकारी नहीं है.

यहां देखा जा सकता है कि XHR को submitHandler()
से शुरू किया गया था. बढ़िया!
असाइन किए गए कॉल स्टैक चालू होने पर, पूरा कॉल स्टैक देखा जा सकता है. इससे यह आसानी से पता चलता है कि अनुरोध submitHandler()
(जो सबमिट बटन पर क्लिक करने के बाद होता है) से शुरू हुआ था या retrySubmit()
(जो setTimeout()
देरी के बाद होता है) से:


वॉच एक्सप्रेशन को अलग-अलग समय पर देखना
पूरे कॉल स्टैक को वॉक करने पर, आपके देखे गए एक्सप्रेशन भी अपडेट हो जाएंगे, ताकि उस समय की स्थिति को दिखाया जा सके!

पिछले स्कोप के कोड का आकलन करना
एक्सप्रेशन को सिर्फ़ देखने के अलावा, DevTools के JavaScript कंसोल पैनल में जाकर, पिछले स्कोप के कोड के साथ इंटरैक्ट किया जा सकता है.
मान लें कि आप डॉ. हू हैं और आपको टार्डिस में जाने से पहले और "अभी" की घड़ी की तुलना करने में थोड़ी मदद चाहिए. DevTools कंसोल से, अलग-अलग एक्सीक्यूशन पॉइंट की वैल्यू का आसानी से आकलन किया जा सकता है, उन्हें सेव किया जा सकता है, और उन पर हिसाब लगाया जा सकता है.

एक्सप्रेशन में बदलाव करने के लिए, DevTools में बने रहने से आपको सोर्स कोड पर वापस स्विच करने, बदलाव करने, और ब्राउज़र को रीफ़्रेश करने में लगने वाला समय बचेगा.
चेन किए गए प्रॉमिस रिज़ॉल्यूशन को अनरॉल करना
अगर आपको लगता है कि असाइन किए गए कॉल स्टैक की सुविधा चालू किए बिना, Gmail के पिछले मॉक फ़्लो को समझना मुश्किल था, तो क्या आपको लगता है कि चेन किए गए प्रॉमिस जैसे ज़्यादा जटिल असाइन किए गए फ़्लो के साथ यह कितना मुश्किल होगा? JavaScript के प्रॉमिस के बारे में जेक आर्किबाल्ड के ट्यूटोरियल के आखिरी उदाहरण पर फिर से नज़र डालते हैं.
यहां जैक के async-best-example.html उदाहरण में, कॉल स्टैक को वॉक करने का एक छोटा ऐनिमेशन दिया गया है.

ध्यान दें कि कॉल स्टैक पैनल में, प्रॉमिस को डीबग करने के दौरान बहुत कम जानकारी दिखती है.

वाह! ऐसे वादे. बहुत ज़्यादा कॉलबैक.
अपने वेब ऐनिमेशन के बारे में अहम जानकारी पाना
आइए, HTML5Rocks के संग्रह के बारे में ज़्यादा जानें. क्या आपको पॉल लुइस का requestAnimationFrame की मदद से, बेहतर, ज़्यादा बेहतर, और तेज़ ऐनिमेशन लेख याद है?
requestAnimationFrame डेमो खोलें और post.html के update() तरीके की शुरुआत में ब्रेकपॉइंट जोड़ें. यह तरीका, लाइन 874 के आस-पास होता है. असाइन किए गए कॉल स्टैक की मदद से, हमें requestAnimationFrame के बारे में ज़्यादा जानकारी मिलती है. इसमें, स्क्रोल इवेंट कॉलबैक तक वापस जाने की सुविधा भी शामिल है.


MutationObserver का इस्तेमाल करते समय, DOM के अपडेट को ट्रैक करना
MutationObserver
की मदद से, हम DOM में होने वाले बदलावों को देख सकते हैं. इस साधारण उदाहरण में, बटन पर क्लिक करने पर, <div class="rows"></div>
में एक नया डीओएम नोड जोड़ा जाता है.
demo.html में nodeAdded()
(लाइन 31) में ब्रेकपॉइंट जोड़ें. असाइन किए गए कॉल स्टैक चालू होने पर, अब कॉल स्टैक को addNode()
से शुरुआती क्लिक इवेंट पर वापस लाया जा सकता है.


एक साथ काम नहीं करने वाले कॉल स्टैक में JavaScript को डीबग करने के बारे में सलाह
अपने फ़ंक्शन को नाम देना
अगर आपने अपने सभी कॉलबैक को बिना नाम वाले फ़ंक्शन के तौर पर असाइन किया है, तो कॉल स्टैक को आसानी से देखने के लिए, उन्हें नाम दिया जा सकता है.
उदाहरण के लिए, इस तरह का कोई अनाम फ़ंक्शन लें:
window.addEventListener('load', function() {
// do something
});
और इसे कोई नाम दें, जैसे कि windowLoaded()
:
window.addEventListener('load', function <strong>windowLoaded</strong>(){
// do something
});
जब लोड इवेंट ट्रिगर होगा, तो वह DevTools स्टैक ट्रेस में अपने फ़ंक्शन के नाम के साथ दिखेगा. यह नाम, "(बिना नाम वाला फ़ंक्शन)" के बजाय दिखेगा. इससे, एक नज़र में यह देखना बहुत आसान हो जाता है कि आपके स्टैक ट्रेस में क्या हो रहा है.


आगे एक्सप्लोर करें
आपको याद दिला दें कि ये ऐसे सभी असाइनोक्रोनस कॉलबैक हैं जिनमें DevTools, कॉल का पूरा स्टैक दिखाएगा:
- टाइमर:
setTimeout()
याsetInterval()
को शुरू करने के लिए, उस जगह पर वापस जाएं. - एक्सएचआर:
xhr.send()
को कॉल करने वाले पेज पर वापस जाएं. - ऐनिमेशन फ़्रेम:
requestAnimationFrame
को कॉल करने वाली जगह पर वापस जाएं. - प्रॉमिस: वह जगह वापस जाएं जहां प्रॉमिस पूरा हो चुका है.
- Object.observe: वहां वापस जाएं जहां ऑब्ज़र्वर कॉलबैक को मूल रूप से बाउंड किया गया था.
- MutationObservers: वह जगह देखें जहां म्यूटेशन ऑब्ज़र्वर इवेंट ट्रिगर हुआ था.
- window.postMessage(): प्रोसेस के बीच मैसेज भेजने की सुविधा.
- DataTransferItem.getAsString()
- FileSystem API
- IndexedDB
- WebSQL
addEventListener()
की मदद से, ज़रूरी शर्तें पूरी करने वाले DOM इवेंट: जिस जगह पर इवेंट ट्रिगर हुआ था वहां वापस जाएं. परफ़ॉर्मेंस की वजह से, सभी DOM इवेंट, असाइन किए गए कॉल स्टैक की सुविधा के लिए ज़रूरी शर्तें पूरी नहीं करते. फ़िलहाल उपलब्ध इवेंट के उदाहरणों में ये शामिल हैं: 'scroll', 'hashchange', और 'selectionchange'.addEventListener()
की मदद से मल्टीमीडिया इवेंट: वह जगह वापस जाएं जहां इवेंट ट्रिगर हुआ था. उपलब्ध मल्टीमीडिया इवेंट में ये शामिल हैं: ऑडियो और वीडियो इवेंट (उदाहरण के लिए, 'चलाएं', 'रोकें', 'गति बदलें'), WebRTC MediaStreamTrackList इवेंट (उदाहरण के लिए, 'addtrack', 'removetrack'), और MediaSource इवेंट (उदाहरण के लिए, 'sourceopen').
अपने JavaScript कॉलबैक का पूरा स्टैक ट्रेस देखने से, आपको समस्या हल करने में मदद मिलेगी. DevTools में यह सुविधा खास तौर पर तब मददगार होगी, जब एक-दूसरे के हिसाब से कई असाइनिक इवेंट हों या असाइनिक कॉलबैक में कोई ऐसा अपवाद हो जो पकड़ा न गया हो.
इसे Chrome में आज़माएं. अगर आपको इस नई सुविधा के बारे में सुझाव, शिकायत या राय देनी है, तो हमें Chrome DevTools के बग ट्रैकर या Chrome DevTools ग्रुप पर लिखें.