याद रखें कि जब जावास्क्रिप्ट एकल-थ्रेडेड होता है, तो नोड के I / O के सभी और देशी API को कॉल या तो अतुल्यकालिक (प्लेटफ़ॉर्म-विशिष्ट तंत्र का उपयोग करके) होते हैं, या एक अलग थ्रेड पर चलते हैं। (यह सब लिबवू के जरिए संभाला गया है।)
इसलिए जब एक सॉकेट या एक देशी एपीआई फ़ंक्शन पर डेटा उपलब्ध होता है, तो हमें जावास्क्रिप्ट फ़ंक्शन को आमंत्रित करने के लिए एक सिंक्रनाइज़ तरीके की आवश्यकता होती है जो उस विशेष घटना में रुचि रखता है जो अभी हुआ था।
यह केवल जेएस फ़ंक्शन को थ्रेड से कॉल करने के लिए सुरक्षित नहीं है, जहां मूल घटना उन्हीं कारणों से हुई है जो आप एक नियमित बहु-थ्रेडेड एप्लिकेशन - रेस की स्थिति, गैर-परमाणु मेमोरी एक्सेस, और इसके बाद से मुठभेड़ करेंगे।
तो हम जो करते हैं, वह घटना को एक कतार में थ्रेड-सेफ तरीके से रखता है। ओवरसाइप्लाइज़्ड प्यूसीकोड में, कुछ इस तरह से:
lock (queue) {
queue.push(event);
}
फिर, मुख्य जावास्क्रिप्ट थ्रेड पर वापस (लेकिन चीजों के सी तरफ), हम कुछ ऐसा करते हैं:
while (true) {
lock (queue) {
var tickEvents = copy(queue);
queue.empty();
}
for (var i = 0; i < tickEvents.length; i++) {
InvokeJSFunction(tickEvents[i]);
}
}
while (true)
(जो वास्तव में नोड के स्रोत कोड में मौजूद नहीं है, यह विशुद्ध रूप से उदाहरण है) का प्रतिनिधित्व करता घटना पाश । आंतरिक for
प्रत्येक घटना के लिए JS फ़ंक्शन को आमंत्रित करता है जो कतार में था।
यह एक टिक है: किसी भी बाहरी घटनाओं के साथ जुड़े शून्य या अधिक कॉलबैक फ़ंक्शंस का तुल्यकालिक आह्वान। एक बार कतार को खाली कर दिया जाता है और अंतिम फ़ंक्शन वापस आ जाता है, तो टिक खत्म हो जाता है। हम शुरुआत (अगले टिक) पर जाते हैं और उन घटनाओं की जांच करते हैं जो हमारे जावास्क्रिप्ट को चलाने के दौरान अन्य थ्रेड्स से कतार में जोड़े गए थे ।
क्या चीजों को कतार में जोड़ सकते हैं?
process.nextTick
setTimeout
/setInterval
- आई / ओ (से सामान
fs
, net
, और आगे)
crypto
क्रिप्टो स्ट्रीम, pbkdf2, और PRNG जैसे प्रोसेसर के गहन कार्य (जो वास्तव में एक उदाहरण हैं ...)
- कोई भी देशी मॉड्यूल जो सिंक्रोनस C / C ++ लाइब्रेरी कॉल को अतुल्यकालिक बनाने के लिए libuv कार्य कतार का उपयोग करता है