परिचय
जावास्क्रिप्ट को ज्यादातर Node.js और ब्राउज़र में एक ही थ्रेड पर निष्पादित किया जाता है (वर्कर थ्रेड जैसे कुछ अपवादों के साथ, जो वर्तमान लेख के दायरे से बाहर है)। इस लेख में, मैं Node.js पर समवर्ती के तंत्र को समझाने की कोशिश करूंगा जो कि इवेंट लूप है।
इस लेख को पढ़ना शुरू करने से पहले आपको स्टैक से परिचित होना चाहिए और यह कैसे काम करता है, मैंने इस विचार के बारे में पहले लिखा था, इसलिए स्टैक और हीप देखें - उन्हें समझे बिना कोड करना शुरू न करें - मोशे बिनिएली | मध्यम
परिचय छवि
उदाहरण
मेरा मानना है कि उदाहरणों से सीखना सबसे अच्छा है, इसलिए मैं 4 सरल कोड उदाहरणों से शुरुआत करूंगा। मैं उदाहरणों का विश्लेषण करूंगा और फिर Node.js की वास्तुकला में उतरूंगा।
उदाहरण 1:
कंसोल.लॉग(1);
कंसोल.लॉग(2);
कंसोल.लॉग(3);
// आउटपुट:
// 1
// 2
//3
यह उदाहरण बहुत आसान है, पहले चरण में कंसोल.लॉग(1) कॉल स्टैक में जाता है, निष्पादित किया जाता है और फिर हटा दिया जाता है, दूसरे चरण में कंसोल.लॉग(2) कॉल स्टैक में जाता है, निष्पादित किया जाता है और फिर हटा दिया गया, और इसी तरह कंसोल.लॉग(3).
उदाहरण 1 के लिए कॉल स्टैक का विज़ुअलाइज़ेशन
उदाहरण 2:
कंसोल.लॉग(1);
सेटटाइमआउट(फ़ंक्शन foo(){
कंसोल.लॉग(2);
}, 0);
कंसोल.लॉग(3);
// आउटपुट:
// 1
//3
// 2
हम इस उदाहरण में देख सकते हैं कि हम तुरंत सेटटाइमआउट चलाते हैं, इसलिए हम उम्मीद करेंगे कि कंसोल.लॉग(2) कंसोल.लॉग(3) से पहले होगा, लेकिन यह मामला नहीं है और आइए इसके पीछे के तंत्र को समझें।
बेसिक इवेंट लूप आर्किटेक्चर (हम बाद में इसके बारे में और विस्तार से जानेंगे)
ढेर और ढेर: इस बारे में मेरा लेख देखें (मैंने इस लेख की शुरुआत में लिंक जोड़ा है)
वेब एपिस: वे आपके वेब ब्राउज़र में निर्मित होते हैं, और ब्राउज़र और आसपास के कंप्यूटर वातावरण से डेटा को उजागर करने और इसके साथ उपयोगी जटिल चीजें करने में सक्षम होते हैं। वे स्वयं जावास्क्रिप्ट भाषा का हिस्सा नहीं हैं, बल्कि वे मूल जावास्क्रिप्ट भाषा के शीर्ष पर बनाए गए हैं, जो आपको अपने जावास्क्रिप्ट कोड में उपयोग करने के लिए अतिरिक्त महाशक्तियाँ प्रदान करते हैं। उदाहरण के लिए, जियोलोकेशन एपीआई स्थान डेटा पुनर्प्राप्त करने के लिए कुछ सरल जावास्क्रिप्ट निर्माण प्रदान करता है ताकि आप कह सकें, Google मानचित्र पर अपना स्थान प्लॉट करें। पृष्ठभूमि में, ब्राउज़र वास्तव में डिवाइस के जीपीएस हार्डवेयर (या स्थिति डेटा निर्धारित करने के लिए जो भी उपलब्ध है) के साथ संचार करने, स्थिति डेटा पुनर्प्राप्त करने और इसे ब्राउज़र वातावरण में उपयोग करने के लिए वापस करने के लिए कुछ जटिल निचले-स्तरीय कोड (जैसे सी) का उपयोग कर रहा है। आपके कोड में. लेकिन फिर, एपीआई द्वारा इस जटिलता को आपसे दूर कर दिया गया है।
इवेंट लूप और कॉलबैक कतार: वेब एपिस निष्पादन को समाप्त करने वाले फ़ंक्शन को कॉलबैक कतार में ले जाया जा रहा है, यह एक नियमित कतार डेटा संरचना है, और इवेंट लूप कॉलबैक कतार से अगले फ़ंक्शन को हटाने और फ़ंक्शन को भेजने के लिए जिम्मेदार है फ़ंक्शन निष्पादित करने के लिए कॉल स्टैक।
निष्पादन का आदेश
वर्तमान में कॉल स्टैक में मौजूद सभी फ़ंक्शन निष्पादित हो जाते हैं और फिर वे कॉल-स्टैक से बाहर हो जाते हैं।
जब कॉल स्टैक खाली होता है, तो सभी कतारबद्ध कार्य एक-एक करके कॉल-स्टैक पर पॉप होते हैं और निष्पादित होते हैं, और फिर वे कॉल-स्टैक से बाहर हो जाते हैं।
आइए उदाहरण 2 को समझें
console.log(1) विधि को कॉल किया जाता है और कॉल स्टैक पर रखा जाता है और निष्पादित किया जाता है।
सेटटाइमआउट विधि को कॉल किया जाता है और कॉल स्टैक पर रखा जाता है और निष्पादित किया जाता है, यह निष्पादन 0 मिलीसेकंड के लिए सेटटाइमआउट वेब एपीआई के लिए एक नई कॉल बनाता है, जब यह समाप्त हो जाता है (तुरंत, या यदि अधिक सटीक होना है तो यह होगा) "जितनी जल्दी हो सके" कहना बेहतर होगा) वेब एपीआई कॉल को कॉलबैक कतार में ले जाता है।
console.log(3) विधि को कॉल किया जाता है और कॉल स्टैक पर रखा जाता है और निष्पादित किया जाता है।
इवेंट लूप देखता है कि कॉल स्टैक खाली है और कॉलबैक कतार से "foo" विधि निकालता है और इसे कॉल स्टैक में रखता है, फिर कंसोल.लॉग(2) निष्पादित किया जा रहा है।
उदाहरण 2 के लिए प्रक्रिया का विज़ुअलाइज़ेशन
इसलिए सेटटाइमआउट (फ़ंक्शन, विलंब) में विलंब पैरामीटर सटीक समय विलंब के लिए खड़ा नहीं होता है जिसके बाद फ़ंक्शन निष्पादित होता है। यह प्रतीक्षा करने के लिए न्यूनतम समय को दर्शाता है जिसके बाद किसी समय फ़ंक्शन निष्पादित किया जाएगा।
उदाहरण 3:
कंसोल.लॉग(1);
सेटटाइमआउट(फ़ंक्शन foo() {
कंसोल.लॉग('foo');
}, 3500);
सेटटाइमआउट(फ़ंक्शन बू() {
कंसोल.लॉग('बू');
}, 1000);
कंसोल.लॉग(2);
// आउटपुट:
// 1
// 2
// 'बू'
// 'फू'
उदाहरण 3 के लिए प्रक्रिया का विज़ुअलाइज़ेशन
उदाहरण 4:
कंसोल.लॉग(1);
सेटटाइमआउट(फ़ंक्शन foo() {
कंसोल.लॉग('foo');
}, 6500);
सेटटाइमआउट(फ़ंक्शन बू() {
कंसोल.लॉग('बू');
}, 2500);
सेटटाइमआउट(फ़ंक्शन baz() {
कंसोल.लॉग('बाज़');
}, 0);
के लिए (['ए', 'बी'] का स्थिरांक मान) {
कंसोल.लॉग(मान);
}
फ़ंक्शन दो() {
कंसोल.लॉग(2);
}
दो();
// आउटपुट:
// 1
// 'ए'
// 'बी'
// 2
// 'बाज़'
// 'बू'
// 'फू'
उदाहरण 4 के लिए प्रक्रिया का विज़ुअलाइज़ेशन
इवेंट लूप कार्य कतार में प्रतीक्षा कर रहे सभी कॉलबैक को निष्पादित करने के लिए आगे बढ़ता है। कार्य कतार के अंदर, कार्यों को मोटे तौर पर दो श्रेणियों में वर्गीकृत किया जाता है, अर्थात् सूक्ष्म-कार्य और स्थूल-कार्य।
मैक्रो-कार्य (कार्य कतार) और माइक्रो-कार्य
अधिक सटीक होने के लिए वास्तव में दो प्रकार की कतारें हैं।
कुछ और कार्य हैं जो मैक्रो-टास्क कतार और माइक्रो-टास्क कतार में जाते हैं लेकिन मैं सामान्य लोगों को कवर करूंगा।
सामान्य मैक्रो-कार्य सेटटाइमआउट, सेटइंटरवल और सेटइमीडिएट हैं।
सामान्य माइक्रो-टास्क प्रोसेस.नेक्स्टटिक और प्रॉमिस कॉलबैक हैं।
निष्पादन का आदेश
वर्तमान में कॉल स्टैक में मौजूद सभी फ़ंक्शन निष्पादित हो जाते हैं और फिर वे कॉल-स्टैक से बाहर हो जाते हैं।
जब कॉल स्टैक खाली होता है, तो सभी कतारबद्ध माइक्रो-कार्य एक-एक करके कॉल-स्टैक पर पॉप होते हैं और निष्पादित होते हैं, और फिर वे कॉल-स्टैक से बाहर हो जाते हैं।
जब कॉल-स्टैक और माइक्रो-टास्क कतार दोनों खाली होते हैं, तो सभी कतारबद्ध मैक्रो-कार्य एक-एक करके कॉल-स्टैक पर पॉप होते हैं और निष्पादित होते हैं, और फिर वे कॉल-स्टैक से बाहर हो जाते हैं।
उदाहरण 5:
कंसोल.लॉग(1);
सेटटाइमआउट(फ़ंक्शन foo() {
कंसोल.लॉग('foo');
}, 0);
वादा.संकल्प()
.तब(फ़ंक्शन बू() {
कंसोल.लॉग('बू');
});
कंसोल.लॉग(2);
// आउटपुट:
// 1
// 2
// 'बू'
// 'फू'
कंसोल.लॉग(1) विधि को कॉल किया गया है और कॉल स्टैक पर रखा गया है और निष्पादित किया जा रहा है।
सेटटाइमआउट निष्पादित किया जा रहा है, कंसोल.लॉग('foo') को सेटटाइमआउट वेब एपीआई में ले जाया जाता है, और 0 मिलीसेकंड बाद यह मैक्रो-टास्क कतार में चला जाता है।
Promise.resolve() को कॉल किया जा रहा है, इसे हल किया जा रहा है और फिर .then() विधि को माइक्रो-टास्क कतार में ले जाया गया है।
कंसोल.लॉग(2) विधि को कॉल किया गया है और कॉल स्टैक पर रखा गया है और निष्पादित किया जा रहा है।
इवेंट लूप देखता है कि कॉल-स्टैक खाली है, यह सबसे पहले माइक्रो-टास्क कतार से कार्य लेता है जो कि प्रॉमिस कार्य है, कॉल-स्टैक पर कंसोल.लॉग ('बू') डालता है और इसे निष्पादित करता है।
इवेंट लूप देखता है कि कॉल-स्टैक खाली है, फिर यह देखता है कि माइक्रो-टास्क खाली है, फिर यह मैक्रो-टास्क कतार से अगला कार्य लेता है जो सेटटाइमआउट कार्य है, कंसोल.लॉग ('foo') डालता है कॉल-स्टैक पर और इसे निष्पादित करता है।
उदाहरण 5 के लिए प्रक्रिया का विज़ुअलाइज़ेशन
इवेंट लूप की उन्नत समझ
मैं इवेंट लूप तंत्र के निम्न स्तर के काम करने के बारे में लिखने के बारे में सोच रहा था, यह अपने आप में एक पोस्ट हो सकता है, इसलिए मैंने विषय का परिचय देने और अच्छे लिंक संलग्न करने का निर्णय लिया जो विषय को गहराई से समझाते हों।
इवेंट लूप निचले स्तर की व्याख्या
जब Node.js प्रारंभ होता है, तो यह ईवेंट लूप प्रारंभ करता है, प्रदान की गई इनपुट स्क्रिप्ट को संसाधित करता है (या REPL में छोड़ देता है) जो async API कॉल, शेड्यूल टाइमर, या कॉल प्रोसेस.नेक्स्टटिक () कर सकता है, फिर ईवेंट लूप को संसाधित करना शुरू करता है। &&&]
संचालन के इवेंट-लूप क्रम का सरलीकृत अवलोकन
प्रत्येक चरण में निष्पादित करने के लिए कॉलबैक की एक फीफो कतार होती है (मैं इसे यहां सावधानी से कह रहा हूं क्योंकि कार्यान्वयन के आधार पर एक और डेटा संरचना हो सकती है)। जबकि प्रत्येक चरण अपने तरीके से विशेष होता है, आम तौर पर, जब ईवेंट लूप किसी दिए गए चरण में प्रवेश करता है, तो यह उस चरण के लिए विशिष्ट कोई भी ऑपरेशन करेगा, फिर उस चरण की कतार में कॉलबैक निष्पादित करेगा जब तक कि कतार समाप्त न हो जाए या कॉलबैक की अधिकतम संख्या समाप्त न हो जाए। निष्पादित किया है. जब कतार समाप्त हो जाती है या कॉलबैक सीमा पूरी हो जाती है, तो इवेंट लूप अगले चरण में चला जाएगा, इत्यादि।
टाइमर: यह चरण सेटटाइमआउट() और सेटइंटरवल() द्वारा निर्धारित कॉलबैक निष्पादित करता है।
लंबित कॉलबैक: अगले लूप पुनरावृत्ति के लिए स्थगित I/O कॉलबैक निष्पादित करता है।
निष्क्रिय, तैयारी: केवल आंतरिक रूप से उपयोग किया जाता है।
पोल: नए I/O इवेंट पुनः प्राप्त करें; I/O संबंधित कॉलबैक निष्पादित करें (लगभग सभी करीबी कॉलबैक के अपवाद के साथ, टाइमर द्वारा निर्धारित, और setImmediate()); उपयुक्त होने पर नोड यहां ब्लॉक हो जाएगा।
जांचें: setImmediate() कॉलबैक यहां लागू किए गए हैं।
कॉलबैक बंद करें: कुछ करीबी कॉलबैक, उदा. सॉकेट.ऑन('बंद करें',...).
पिछले चरण यहां कैसे फिट बैठते हैं?
तो केवल "कॉलबैक कतार" और फिर "मैक्रो और माइक्रो कतार" के साथ पिछले चरण इवेंट लूप कैसे काम करता है, इसके बारे में अमूर्त स्पष्टीकरण थे।
चरण 1: ईवेंट लूप वर्तमान निष्पादन के लिए लूप समय को वर्तमान समय में अपडेट करता है।
चरण 2: माइक्रो-क्यू निष्पादित किया गया है।
चरण 3: टाइमर चरण से एक कार्य निष्पादित किया जाता है।
चरण 4: जाँच करना कि माइक्रो-क्यू में कुछ है या नहीं और यदि कुछ है तो संपूर्ण माइक्रो-क्यू निष्पादित करता है।
चरण 5: टाइमर चरण खाली होने तक चरण 3 पर लौटता है।
चरण 6: लंबित कॉलबैक चरण से एक कार्य निष्पादित किया जाता है।
चरण 7: जाँच करना कि माइक्रो-क्यू में कुछ है या नहीं और यदि कुछ है तो संपूर्ण माइक्रो-क्यू निष्पादित करता है।
चरण 8: लंबित कॉलबैक चरण खाली होने तक चरण 6 पर लौटता है।
और फिर निष्क्रिय... माइक्रो-क्यू... पोल... माइक्रो-क्यू... चेक करें... माइक्रो-क्यू... कॉलबैक बंद करें और फिर यह फिर से शुरू होता है।
इसलिए मैंने इस बात का एक अच्छा अवलोकन दिया कि इवेंट लूप वास्तव में पर्दे के पीछे कैसे काम करता है, बहुत सारे गायब हिस्से हैं जिनका मैंने यहां उल्लेख नहीं किया है क्योंकि वास्तविक दस्तावेज़ीकरण इसे समझाने में बहुत अच्छा काम कर रहा है, मैं इसके लिए बेहतरीन लिंक प्रदान करूंगा दस्तावेज़ीकरण, मैं आपको 10-20 मिनट निवेश करने और उन्हें समझने के लिए प्रोत्साहित करता हूं।
अस्वीकरण: उपलब्ध कराए गए सभी संसाधन आंशिक रूप से इंटरनेट से हैं। यदि आपके कॉपीराइट या अन्य अधिकारों और हितों का कोई उल्लंघन होता है, तो कृपया विस्तृत कारण बताएं और कॉपीराइट या अधिकारों और हितों का प्रमाण प्रदान करें और फिर इसे ईमेल पर भेजें: [email protected] हम इसे आपके लिए यथाशीघ्र संभालेंगे।
Copyright© 2022 湘ICP备2022001581号-3