एक घटना पाश संदर्भ के भीतर microtask और macrotask के बीच अंतर


140

मैंने अभी-अभी प्रोमोज़ / ए + विनिर्देश को पढ़ना समाप्त किया है और शर्तों पर टकराया है माइक्रोटस्क और मैक्रोस्कैस: देखें http://promisesaplus.com/#notes

मैंने पहले कभी इन शर्तों के बारे में नहीं सुना है, और अब मैं उत्सुक हूं कि क्या अंतर हो सकता है?

मैंने पहले से ही वेब पर कुछ जानकारी खोजने की कोशिश की है, लेकिन मैंने पाया है कि यह पोस्ट w3.org अभिलेखागार से है (जो मुझे अंतर नहीं समझाता है): http://lists.w3.org/Archives /Public/public-nextweb/2013Jul/0018.html

इसके अतिरिक्त, मुझे "macrotask" नामक एक npm मॉड्यूल मिला है: https://www.npmjs.org/package/macrotask अगेन, यह स्पष्ट नहीं किया गया है कि वास्तव में क्या अंतर है।

मुझे पता है कि यह घटना लूप के साथ कुछ करना है, जैसा कि https://html.spec.whatwg.org/multipage/webappapis.html#task-queue और https: //html.spec.whatwg में वर्णित है। .org / मल्टीपेज / webappapis.html # प्रदर्शन एक microtask-चौकी

मुझे पता है कि मुझे सैद्धांतिक रूप से इस WHATWG विनिर्देश को देखते हुए मतभेदों को निकालने में सक्षम होना चाहिए। लेकिन मुझे यकीन है कि एक विशेषज्ञ द्वारा दी गई संक्षिप्त व्याख्या से दूसरों को भी फायदा हो सकता है।


संक्षेप में: एकाधिक नेस्टेड इवेंट कतार। आप स्वयं को लागू भी कर सकते हैं:while (task = todo.shift()) task();
बर्गी

1
किसी ऐसे व्यक्ति के लिए जो अधिक जानकारी चाहता है: जावास्क्रिप्ट निंजा का रहस्य, दूसरा संस्करण, अध्याय 13 उत्तरजीविता की घटनाएँ
एथान

जवाबों:


220

ईवेंट लूप के चारों ओर जाने के लिए मैक्रोट्रैस क्यू से संसाधित किया जा रहा ठीक एक कार्य होगा (इस कतार को बस WHATWG विनिर्देश में कार्य कतार कहा जाता है )। इसके बाद मैक्रोटस्क समाप्त हो गया है, सभी उपलब्ध माइक्रोटेस्क को संसाधित किया जाएगा, अर्थात् एक ही गो-के आसपास चक्र के भीतर। जबकि इन माइक्रोटस्क को संसाधित किया जाता है, वे और भी अधिक माइक्रोट्यूज़ को कतारबद्ध कर सकते हैं, जो सभी तब तक एक-एक करके चलाए जाएंगे, जब तक कि माइक्रोटस्क कतार समाप्त नहीं हो जाती।

इसके व्यावहारिक परिणाम क्या हैं?

यदि कोई माइक्रोटस्क पुनरावर्ती रूप से अन्य माइक्रोटेक को कतार में रखता है, तो अगले मैक्रोटस्क को संसाधित होने तक एक लंबा समय लग सकता है। इसका मतलब है, आप एक अवरुद्ध यूआई के साथ समाप्त हो सकते हैं, या आपके आवेदन में कुछ समाप्त I / O निष्क्रिय हो सकते हैं।

हालाँकि, कम से कम Node.js की प्रक्रिया के बारे में। स्नेक्सटीक फंक्शन (जो माइक्रोएकट्स को कतार में रखता है ), इस तरह के ब्लॉकिंग के खिलाफ इनबिल्ट प्रोटेक्शन होता है। process.maxTickDepth। यह मान 1000 के डिफॉल्ट पर सेट है, इस सीमा तक पहुंचने के बाद माइक्रोटेक्सेस की आगे की प्रक्रिया में कटौती की जाती है, जो अगले मैक्रोटस्क को संसाधित करने की अनुमति देता है)

तो कब क्या उपयोग करें?

मूल रूप से, माइक्रो- मास्क का उपयोग करें जब आपको सामान रूप से समकालिक तरीके से करने की आवश्यकता होती है (अर्थात जब आप कहेंगे कि यह (सूक्ष्म-) कार्य सबसे तत्काल भविष्य में करें )। अन्यथा, मैक्रोटेस से चिपके रहें

उदाहरण

macrotasks: setTimeout , setInterval , setImmediate , requestAnimationFrame , आई / ओ , यूआई प्रतिपादन
microtasks: process.nextTick , वादे , queueMicrotask , MutationObserver


4
हालाँकि, इवेंट लूप में एक माइक्रोटस्क चेकपॉइंट होता है, लेकिन यह वह जगह नहीं है जहाँ अधिकांश डेवलपर्स माइक्रोट्स्क का सामना करेंगे। जब जेएस स्टैक खाली हो जाता है तो माइक्रोटेस्क संसाधित होते हैं। यह कई बार किसी कार्य के भीतर या इवेंट लूप के रेंडर चरणों के भीतर भी हो सकता है।
JaffaTheCake

2
process.maxTickDepthबहुत पहले हटा दिया गया था: github.com/nodejs/node/blob/…
RidgeA

आप एक नया माइक्रोटैस्क जोड़ने के लिए queueMicrotask () विधि का भी उपयोग कर सकते हैं
ZoomAll

धन्यवाद @ZoomAll, अब तक क्यूमाइक्रोटक () नहीं जानता था। मैंने इसे सभी सामानों के उत्तर प्लस लिंक के साथ जोड़ दिया है ...
निकब्राइट

requestAnimationFrame (rAF) न केवल माइक्रोटेक्सेस उत्पन्न करता है। आम तौर पर rAF कॉल बोलने से एक अलग कतार बन जाती है
ZoomAll

67

कल्पना में मूल अवधारणाएँ :

  • एक ईवेंट लूप में एक या अधिक कार्य कतारें होती हैं। (कार्य कतार मैक्रोटस्क कतार है)
  • प्रत्येक ईवेंट लूप में एक माइक्रोटस्क क्यू है।
  • कार्य कतार = मैक्रोटस्क कतार! = माइक्रोटस्क कतार
  • एक कार्य को मैक्रोटस्क कतार, या माइक्रोटस्क कतार में धकेला जा सकता है
  • जब किसी कार्य को एक कतार (माइक्रो / मैक्रो) में धकेल दिया जाता है, तो हमारा मतलब है कि कार्य तैयार करना समाप्त हो गया है, इसलिए कार्य को अब निष्पादित किया जा सकता है।

और इवेंट लूप प्रक्रिया मॉडल निम्नानुसार है:

जब कॉल स्टैक खाली होता है, तो स्टेप्स करें-

  1. कार्य कतार में सबसे पुराना कार्य (A) चुनें
  2. यदि कार्य A शून्य है (मतलब कार्य कतार खाली है), तो चरण 6 पर जाएं
  3. "वर्तमान में चल रहा कार्य" को "कार्य A" पर सेट करें
  4. रन "टास्क ए" (मतलब कॉलबैक फंक्शन चलाएं)
  5. "वर्तमान में चल रहा कार्य" शून्य करने के लिए सेट करें, "कार्य A" निकालें
  6. माइक्रोटस्क कतार प्रदर्शन
    • (a) माइक्रोएस्क कतार में सबसे पुराना कार्य (कार्य x) चुनें
    • (b) .if कार्य x अशक्त है (इसका अर्थ है कि माइक्रोटस्क कतार खाली है), स्टेप (छ) पर जाएं
    • (ग) .सेट "वर्तमान में चल रहा कार्य" से "कार्य x"
    • (d) .run "task x"
    • (ई) .सेट "वर्तमान में चल रहे कार्य" को शून्य करने के लिए, "कार्य x" को हटा दें
    • (च)। माइक्रोएटस कतार में अगला सबसे पुराना कार्य, स्टेप (b) पर जाएं
    • (छ) .फाइनाइट माइक्रोटस्क क्यू;
  7. चरण 1 पर जाएं।

एक सरलीकृत प्रक्रिया मॉडल इस प्रकार है:

  1. मैक्रोटस्क कतार में सबसे पुराना कार्य चलाएं, फिर इसे हटा दें।
  2. सभी उपलब्ध कार्यों को माइक्रोटस्क कतार में चलाएं, फिर उन्हें हटा दें।
  3. अगला राउंड: मैक्रोटस्क कतार में अगला कार्य चलाएं (स्टेप 2 कूदें)

कुछ याद करने योग्य:

  1. जब कोई कार्य (मैक्रोटस्क कतार में) चल रहा होता है, तो नई घटनाएँ पंजीकृत हो सकती हैं। नए कार्य बनाए जा सकते हैं। हालांकि, दो नए बनाए गए कार्य हैं:
    • वादा.एथेन () का कॉलबैक एक काम है
      • वादे को हल / अस्वीकार किया जाता है: कार्य को वर्तमान लूप ऑफ़ इवेंट लूप में माइक्रोटस्क क्यू में धकेल दिया जाएगा।
      • वादा लंबित है: भविष्य के इवेंट लूप में कार्य को माइक्रोटस्क कतार में धकेला जाएगा (अगले दौर में हो सकता है)
    • setTimeout (कॉलबैक, एन) का कॉलबैक एक काम है, और मैक्रोटस्क कतार में धकेल दिया जाएगा, यहां तक ​​कि एन 0 है;
  2. माइक्रोटस्क कतार में कार्य वर्तमान दौर में चलाया जाएगा, जबकि मैक्रोटस्क कतार में कार्य को अगले दौर के इवेंट लूप के लिए इंतजार करना होगा।
  3. हम सभी "क्लिक", "स्क्रॉल", "अजाक्स", "सेटटाइमआउट" के कॉलबैक को जानते हैं ... कार्य हैं, हालांकि हमें यह भी याद रखना चाहिए कि पूरी तरह से स्क्रिप्ट टैग में js कोड भी एक कार्य (मैक्रोटस्क) है।

2
यह महान व्याख्या है! साझा करने के लिए धन्यवाद!। उल्लेख करने के लिए एक और बात NodeJs में है , setImmediate()मैक्रो / कार्य है, और process.nextTick()एक माइक्रो / नौकरी है।
लियोन - हान ली

6
ब्राउज़र paintकार्यों के बारे में क्या ? वे किस श्रेणी में फिट होंगे?
लेजेंड्स

मुझे लगता है कि वे सूक्ष्म कार्यों (जैसे requestAnimationFrame)
दिव्यांशु मैथानी

यहाँ वह क्रम है जिसमें v8 इवेंट लूप चलता है -> कॉल स्टैक || माइक्रो टास्क || कार्य कतार || rAF || रेंडर ट्री || लेआउट || पेंट || स्क्रीन पर पिक्सेल खींचने के लिए <OS Native कॉल> <----- 1) DOM (नए बदलाव), CSSOM (नए बदलाव), रेंडर ट्री, लेआउट और पेंट अनुरोध के बाद होते हैं। इवेंट-लूप टाइमर्स के अनुसार कॉल रिमेम्बरबैक। यही कारण है कि आरएएफ से पहले अपने डोम संचालन को समाप्त करना महत्वपूर्ण है जितना आप कर सकते हैं, बाकी आरएएफ में जा सकते हैं। पुनश्च: आरएएफ को कॉल करने से मैक्रो-टास्क निष्पादन शुरू हो जाएगा।
अनवेश चैक

मुझे नहीं पता कि क्या मैं गलत हूं, लेकिन मैं इस जवाब से सहमत नहीं हूं, माइक्रोट्रॉक्स मैक्रोटस्क से पहले चलता है। codepen.io/walox/pen/yLYjNRq ?
walox

9

मुझे लगता है कि हम स्टैक से अलग होने की घटना लूप पर चर्चा नहीं कर सकते, इसलिए:

JS के तीन "ढेर" हैं:

  • सभी तुल्यकालिक कॉल के लिए मानक स्टैक (एक फ़ंक्शन दूसरे को कॉल करता है, आदि)
  • microtask कतार (या नौकरी कतार या microtask स्टैक) उच्च प्राथमिकता के साथ सभी async संचालन के लिए (प्रक्रिया ।nextTick, वादे, Object.observe, MutationObserver)
  • निचली प्राथमिकता (सेटटाइमआउट, सेटइंटरवाल, सेटइमाउडेट, अनुरोधअनिमेशनफ्रेम, I / O, UI रेंडरिंग) के साथ सभी async संचालन के लिए मैक्रोटस्क कतार (या ईवेंट कतार, कार्य कतार, मैक्रोटस्क कतार )
|=======|
| macro |
| [...] |
|       |
|=======|
| micro |
| [...] |
|       |
|=======|
| stack |
| [...] |
|       |
|=======|

और इवेंट लूप इस तरह से काम करता है:

  • स्टैक से नीचे से ऊपर तक सब कुछ निष्पादित करें, और केवल जब स्टैक खाली हो, तो जांचें कि ऊपर कतारों में क्या चल रहा है
  • माइक्रो स्टैक की जांच करें और स्टैक की मदद से वहां (यदि आवश्यक हो) सब कुछ निष्पादित करें, एक माइक्रो टास्क एक दूसरे के बाद जब तक कि माइक्रोटस्क कतार खाली है या किसी भी निष्पादन की आवश्यकता नहीं है और केवल तब मैक्रो स्टैक की जांच करें
  • मैक्रो स्टैक की जांच करें और स्टैक की मदद से वहां (यदि आवश्यक हो) सब कुछ निष्पादित करें

यदि स्टैक खाली नहीं है तो माइको स्टैक स्पर्श नहीं करेगा। यदि माइक्रो स्टैक खाली नहीं है या किसी निष्पादन की आवश्यकता नहीं है तो मैक्रो स्टैक स्पर्श नहीं करेगा।

योग करने के लिए: माइक्रोटस्क कतार लगभग मैक्रोटस्क कतार के समान है, लेकिन उन कार्यों (प्रक्रिया.nextTick, वादे, Object.observe, MutationObserver) में मैक्रोटॉक्स की तुलना में अधिक प्राथमिकता है।

माइक्रो मैक्रो की तरह है लेकिन उच्च प्राथमिकता के साथ।

यहां आपके पास सब कुछ समझने के लिए "अंतिम" कोड है।

console.log('stack [1]');
setTimeout(() => console.log("macro [2]"), 0);
setTimeout(() => console.log("macro [3]"), 1);

const p = Promise.resolve();
for(let i = 0; i < 3; i++) p.then(() => {
    setTimeout(() => {
        console.log('stack [4]')
        setTimeout(() => console.log("macro [5]"), 0);
        p.then(() => console.log('micro [6]'));
    }, 0);
    console.log("stack [7]");
});

console.log("macro [8]");

/* Result:
stack [1]
macro [8]

stack [7], stack [7], stack [7]

macro [2]
macro [3]

stack [4]
micro [6]
stack [4]
micro [6]
stack [4]
micro [6]

macro [5], macro [5], macro [5]
--------------------
but in node in versions < 11 (older versions) you will get something different


stack [1]
macro [8]

stack [7], stack [7], stack [7]

macro [2]
macro [3]

stack [4], stack [4], stack [4]
micro [6], micro [6], micro [6]

macro [5], macro [5], macro [5]

more info: https://blog.insiderattack.net/new-changes-to-timers-and-microtasks-from-node-v11-0-0-and-above-68d112743eb3
*/

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