क्या वास्तव में एक Node.js ईवेंट लूप टिक है?


84

मैं Node.js आर्किटेक्चर के इंटर्नल्स में अधिक हो रहा हूं, और एक शब्द जो मैं देख रहा हूं, वह बहुत अधिक "टिक" है, जैसा कि "इवेंट लूप के अगले टिक" या फंक्शन नेक्स्ट () में है

मैंने जो नहीं देखा है वह वास्तव में "टिक" क्या है की एक ठोस परिभाषा है। विभिन्न लेखों ( जैसे यह एक ) के आधार पर , मैं एक अवधारणा को अपने सिर में एक साथ करने में सक्षम रहा हूं, लेकिन मुझे यकीन नहीं है कि यह कितना सही है।

क्या मुझे Node.js ईवेंट लूप टिक का सटीक और विस्तृत विवरण मिल सकता है?


अपने "लूप" के बाद से, इसका अर्थ है "अगली बार जब यह लूप करता है", तो एक पूरे लूप को टिक करें, यह तब समाप्त होता है जब कोई घटना नहीं होती है और नोडज ने सभी को जांचने के लिए लूप किया है कि क्या कोई ट्रिगर है, "नेक्स्ट" का अर्थ है अगला वर्तमान एक के बाद लूप।
Gntem

जवाबों:


156

याद रखें कि जब जावास्क्रिप्ट एकल-थ्रेडेड होता है, तो नोड के I / O के सभी और देशी API को कॉल या तो अतुल्यकालिक (प्लेटफ़ॉर्म-विशिष्ट तंत्र का उपयोग करके) होते हैं, या एक अलग थ्रेड पर चलते हैं। (यह सब लिबवू के जरिए संभाला गया है।)

इसलिए जब एक सॉकेट या एक देशी एपीआई फ़ंक्शन पर डेटा उपलब्ध होता है, तो हमें जावास्क्रिप्ट फ़ंक्शन को आमंत्रित करने के लिए एक सिंक्रनाइज़ तरीके की आवश्यकता होती है जो उस विशेष घटना में रुचि रखता है जो अभी हुआ था।

यह केवल जेएस फ़ंक्शन को थ्रेड से कॉल करने के लिए सुरक्षित नहीं है, जहां मूल घटना उन्हीं कारणों से हुई है जो आप एक नियमित बहु-थ्रेडेड एप्लिकेशन - रेस की स्थिति, गैर-परमाणु मेमोरी एक्सेस, और इसके बाद से मुठभेड़ करेंगे।

तो हम जो करते हैं, वह घटना को एक कतार में थ्रेड-सेफ तरीके से रखता है। ओवरसाइप्लाइज़्ड प्यूसीकोड में, कुछ इस तरह से:

lock (queue) {
    queue.push(event);
}

फिर, मुख्य जावास्क्रिप्ट थ्रेड पर वापस (लेकिन चीजों के सी तरफ), हम कुछ ऐसा करते हैं:

while (true) {
    // this is the beginning of a tick

    lock (queue) {
        var tickEvents = copy(queue); // copy the current queue items into thread-local memory
        queue.empty(); // ..and empty out the shared queue
    }

    for (var i = 0; i < tickEvents.length; i++) {
        InvokeJSFunction(tickEvents[i]);
    }

    // this the end of the tick
}

while (true)(जो वास्तव में नोड के स्रोत कोड में मौजूद नहीं है, यह विशुद्ध रूप से उदाहरण है) का प्रतिनिधित्व करता घटना पाश । आंतरिक forप्रत्येक घटना के लिए JS फ़ंक्शन को आमंत्रित करता है जो कतार में था।

यह एक टिक है: किसी भी बाहरी घटनाओं के साथ जुड़े शून्य या अधिक कॉलबैक फ़ंक्शंस का तुल्यकालिक आह्वान। एक बार कतार को खाली कर दिया जाता है और अंतिम फ़ंक्शन वापस आ जाता है, तो टिक खत्म हो जाता है। हम शुरुआत (अगले टिक) पर जाते हैं और उन घटनाओं की जांच करते हैं जो हमारे जावास्क्रिप्ट को चलाने के दौरान अन्य थ्रेड्स से कतार में जोड़े गए थे ।

क्या चीजों को कतार में जोड़ सकते हैं?

  • process.nextTick
  • setTimeout/setInterval
  • आई / ओ (से सामान fs, net, और आगे)
  • cryptoक्रिप्टो स्ट्रीम, pbkdf2, और PRNG जैसे प्रोसेसर के गहन कार्य (जो वास्तव में एक उदाहरण हैं ...)
  • कोई भी देशी मॉड्यूल जो सिंक्रोनस C / C ++ लाइब्रेरी कॉल को अतुल्यकालिक बनाने के लिए libuv कार्य कतार का उपयोग करता है

2
हाँ, आप इस nailed। कतार की नकल और कॉपी पर सभी घटनाओं के माध्यम से चल रहा था जो मैं विशेष रूप से सोच रहा था। हालांकि अब बहुत मायने रखता है। धन्यवाद।
d512

क्या यह प्रसिद्ध "एसिंक्रोनस Iteration पैटर्न" एल्गो है?
स्टेफ

1
@ संजीव, आपको "नियमित नौकरी" से क्या मतलब है? केवल एक चल रहे जावास्क्रिप्ट अनुप्रयोग ही घटनाओं की प्रक्रिया है।
josh3736

2
मैं जोड़ना चाहूंगा कि 0.10.x setImmediateमें भी एक फंक्शन होगा।
डेनियलकान

1
क्या टिक का मतलब इवेंट लूप चरण है?
दूरबीन

10

जावास्क्रिप्ट के लिए उन लोगों के लिए एक सरल जवाब:

समझने वाली पहली बात यह है कि जावास्क्रिप्ट एक "एकल-थ्रेडेड वातावरण" है। यह जावास्क्रिप्ट के व्यवहार को संदर्भित करता है एक बार में "इवेंट लूप" से एक बार में अपने कोड एक के ब्लॉक को निष्पादित करना। नीचे काइल सिम्पसन की पुस्तक ydkJS और बाद में एक स्पष्टीकरण से लिया गया इवेंट लूप का अल्पकालिक कार्यान्वयन है:

// `eventLoop` is an array that acts as a queue (first-in, first-out)
var eventLoop = [ ];
var event;

// keep going "forever"
while (true) {
    // perform a "tick"
    if (eventLoop.length > 0) {
        // get the next event in the queue
        event = eventLoop.shift();

        // now, execute the next event
        try {
            event();
        }
        catch (err) {
            reportError(err);
        }
    }
}

पहले जबकि लूप ईवेंट लूप का अनुकरण करता है। एक टिक "इवेंट लूप कतार" से एक घटना का विघटन है और उक्त घटना का निष्पादन है।

कृपया किसी घटना के घटने और क्रियान्वयन में क्या होता है, इसके बारे में अधिक विस्तृत विवरण के लिए 'जोश 3796' की प्रतिक्रिया देखें।

इसके अलावा, मैं उन लोगों के लिए काइल सिम्पसन की पुस्तक पढ़ने की सलाह देता हूं जो जावास्क्रिप्ट की गहरी समझ प्राप्त करने में रुचि रखते हैं। यह पूरी तरह से स्वतंत्र और खुला स्रोत है और इस लिंक पर पाया जा सकता है: https://github.com/getify/You-Dont-KK-SS

मेरे द्वारा निर्दिष्ट विशिष्ट अनुभाग यहां पाया जा सकता है: https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/sync-async/ch1.md


1

इवेंट लूप टिक का बहुत ही सरल और संक्षिप्त तरीका है:

इसका उपयोग नोड आंतरिक तंत्र द्वारा किया जाता है जहां जब एक कतार पर अनुरोधों का सेट संसाधित होता है तो टिक शुरू किया जाता है जो एक कार्य के पूरा होने का प्रतिनिधित्व करता है


क्या आप अपने उत्तर के लिए कुछ स्रोत प्रदान कर सकते हैं?
किक बट्सॉकी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.